Index: include/clang/Basic/Builtins.h =================================================================== --- include/clang/Basic/Builtins.h +++ include/clang/Basic/Builtins.h @@ -89,11 +89,16 @@ return getRecord(ID).Type; } - /// \brief Return true if this function is a target-specific builtin + /// \brief Return true if this function is a target-specific builtin. bool isTSBuiltin(unsigned ID) const { return ID >= Builtin::FirstTSBuiltin; } + /// \brief Return true if this function has no side effects. + bool isPure(unsigned ID) const { + return strchr(getRecord(ID).Attributes, 'U') != nullptr; + } + /// \brief Return true if this function has no side effects and doesn't /// read memory. bool isConst(unsigned ID) const { @@ -155,7 +160,7 @@ /// \brief Completely forget that the given ID was ever considered a builtin, /// e.g., because the user provided a conflicting signature. void forgetBuiltin(unsigned ID, IdentifierTable &Table); - + /// \brief If this is a library function that comes from a specific /// header, retrieve that header name. const char *getHeaderName(unsigned ID) const { Index: include/clang/Basic/Builtins.def =================================================================== --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -67,6 +67,7 @@ // Builtin::Context class. Currently we have: // n -> nothrow // r -> noreturn +// U -> pure // c -> const // t -> signature is meaningless, use custom typechecking // F -> this is a libc/libm function with a '__builtin_' prefix added. @@ -773,6 +774,22 @@ LIBBUILTIN(vscanf, "icC*Ra", "fS:0:", "stdio.h", ALL_LANGUAGES) LIBBUILTIN(vfscanf, "iP*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES) LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES) +// C99 ctype.h +LIBBUILTIN(isalnum, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isalpha, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isblank, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(iscntrl, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isdigit, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isgraph, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(islower, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isprint, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(ispunct, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isspace, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isxdigit, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(tolower, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(toupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES) + // C99 // In some systems setjmp is a macro that expands to _setjmp. We undefine // it here to avoid having two identical LIBBUILTIN entries. Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -274,7 +274,7 @@ // so build a dependent node to describe the type. if (WantNontrivialTypeSourceInfo) return ActOnTypenameType(S, SourceLocation(), *SS, II, NameLoc).get(); - + NestedNameSpecifierLoc QualifierLoc = SS->getWithLocInContext(Context); QualType T = CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc, II, NameLoc); @@ -283,7 +283,7 @@ return nullptr; } - + if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(*SS, LookupCtx)) return nullptr; @@ -304,7 +304,7 @@ if (ObjectTypePtr && Result.empty()) { // C++ [basic.lookup.classref]p3: // If the unqualified-id is ~type-name, the type-name is looked up - // in the context of the entire postfix-expression. If the type T of + // in the context of the entire postfix-expression. If the type T of // the object expression is of a class type C, the type-name is also // looked up in the scope of class C. At least one of the lookups shall // find a name that refers to (possibly cv-qualified) T. @@ -432,7 +432,7 @@ // Construct a type with type-source information. TypeLocBuilder Builder; Builder.pushTypeSpec(T).setNameLoc(NameLoc); - + T = getElaboratedType(ETK_None, *SS, T); ElaboratedTypeLoc ElabTL = Builder.push(T); ElabTL.setElaboratedKeywordLoc(SourceLocation()); @@ -550,7 +550,7 @@ if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base.getType())) return true; return S->isFunctionPrototypeScope(); - } + } return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope(); } @@ -625,11 +625,11 @@ // FIXME: Should we move the logic that tries to recover from a missing tag // (struct, union, enum) from Parser::ParseImplicitInt here, instead? - + if (!SS || (!SS->isSet() && !SS->isInvalid())) Diag(IILoc, diag::err_unknown_typename) << II; else if (DeclContext *DC = computeDeclContext(*SS, false)) - Diag(IILoc, diag::err_typename_nested_not_found) + Diag(IILoc, diag::err_typename_nested_not_found) << II << DC << SS->getRange(); else if (isDependentScopeSpecifier(*SS)) { unsigned DiagID = diag::err_typename_missing; @@ -643,25 +643,25 @@ SuggestedType = ActOnTypenameType(S, SourceLocation(), *SS, *II, IILoc).get(); } else { - assert(SS && SS->isInvalid() && + assert(SS && SS->isInvalid() && "Invalid scope specifier has already been diagnosed"); } } /// \brief Determine whether the given result set contains either a type name -/// or +/// or static bool isResultTypeOrTemplate(LookupResult &R, const Token &NextToken) { bool CheckTemplate = R.getSema().getLangOpts().CPlusPlus && NextToken.is(tok::less); - + for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I) { if (isa(*I) || isa(*I)) return true; - + if (CheckTemplate && isa(*I)) return true; } - + return false; } @@ -753,7 +753,7 @@ return TypeInBase; } - // Perform lookup for Objective-C instance variables (including automatically + // Perform lookup for Objective-C instance variables (including automatically // synthesized instance variables), if we're in an Objective-C method. // FIXME: This lookup really, really needs to be folded in to the normal // unqualified lookup mechanism. @@ -762,10 +762,10 @@ if (E.get() || E.isInvalid()) return E; } - + bool SecondTry = false; bool IsFilteredTemplateName = false; - + Corrected: switch (Result.getResultKind()) { case LookupResult::NotFound: @@ -776,18 +776,18 @@ // FIXME: Reference? if (getLangOpts().CPlusPlus) return BuildDeclarationNameExpr(SS, Result, /*ADL=*/true); - + // C90 6.3.2.2: - // If the expression that precedes the parenthesized argument list in a - // function call consists solely of an identifier, and if no - // declaration is visible for this identifier, the identifier is + // If the expression that precedes the parenthesized argument list in a + // function call consists solely of an identifier, and if no + // declaration is visible for this identifier, the identifier is // implicitly declared exactly as if, in the innermost block containing // the function call, the declaration // - // extern int identifier (); + // extern int identifier (); + // + // appeared. // - // appeared. - // // We also allow this in C99 as an extension. if (NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *Name, S)) { Result.addDecl(D); @@ -795,9 +795,9 @@ return BuildDeclarationNameExpr(SS, Result, /*ADL=*/false); } } - - // In C, we first see whether there is a tag type by the same name, in - // which case it's likely that the user just forgot to write "enum", + + // In C, we first see whether there is a tag type by the same name, in + // which case it's likely that the user just forgot to write "enum", // "struct", or "union". if (!getLangOpts().CPlusPlus && !SecondTry && isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) { @@ -809,7 +809,7 @@ if (!SecondTry && CCC) { SecondTry = true; if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(), - Result.getLookupKind(), S, + Result.getLookupKind(), S, &SS, std::move(CCC), CTK_ErrorRecovery)) { unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest; @@ -821,8 +821,8 @@ UnderlyingFirstDecl && isa(UnderlyingFirstDecl)) { UnqualifiedDiag = diag::err_no_template_suggest; QualifiedDiag = diag::err_no_member_template_suggest; - } else if (UnderlyingFirstDecl && - (isa(UnderlyingFirstDecl) || + } else if (UnderlyingFirstDecl && + (isa(UnderlyingFirstDecl) || isa(UnderlyingFirstDecl) || isa(UnderlyingFirstDecl))) { UnqualifiedDiag = diag::err_unknown_typename_suggest; @@ -863,28 +863,28 @@ ExprResult E(LookupInObjCMethod(Result, S, Ivar->getIdentifier())); return E; } - + goto Corrected; } } - + // We failed to correct; just fall through and let the parser deal with it. Result.suppressDiagnostics(); return NameClassification::Unknown(); - + case LookupResult::NotFoundInCurrentInstantiation: { - // We performed name lookup into the current instantiation, and there were + // We performed name lookup into the current instantiation, and there were // dependent bases, so we treat this result the same way as any other // dependent nested-name-specifier. - + // C++ [temp.res]p2: - // A name used in a template declaration or definition and that is - // dependent on a template-parameter is assumed not to name a type - // unless the applicable name lookup finds a type name or the name is + // A name used in a template declaration or definition and that is + // dependent on a template-parameter is assumed not to name a type + // unless the applicable name lookup finds a type name or the name is // qualified by the keyword typename. // // FIXME: If the next token is '<', we might want to ask the parser to - // perform some heroics to see if we actually have a + // perform some heroics to see if we actually have a // template-argument-list, which would indicate a missing 'template' // keyword here. return ActOnDependentIdExpression(SS, /*TemplateKWLoc=*/SourceLocation(), @@ -896,7 +896,7 @@ case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: break; - + case LookupResult::Ambiguous: if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && hasAnyAcceptableTemplateNames(Result)) { @@ -917,29 +917,29 @@ break; } } - + // Diagnose the ambiguity and return an error. return NameClassification::Error(); } - + if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && (IsFilteredTemplateName || hasAnyAcceptableTemplateNames(Result))) { // C++ [temp.names]p3: // After name lookup (3.4) finds that a name is a template-name or that // an operator-function-id or a literal- operator-id refers to a set of - // overloaded functions any member of which is a function template if + // overloaded functions any member of which is a function template if // this is followed by a <, the < is always taken as the delimiter of a // template-argument-list and never as the less-than operator. if (!IsFilteredTemplateName) FilterAcceptableTemplateNames(Result); - + if (!Result.empty()) { bool IsFunctionTemplate; bool IsVarTemplate; TemplateName Template; if (Result.end() - Result.begin() > 1) { IsFunctionTemplate = true; - Template = Context.getOverloadedTemplateName(Result.begin(), + Template = Context.getOverloadedTemplateName(Result.begin(), Result.end()); } else { TemplateDecl *TD @@ -948,19 +948,19 @@ IsVarTemplate = isa(TD); if (SS.isSet() && !SS.isInvalid()) - Template = Context.getQualifiedTemplateName(SS.getScopeRep(), + Template = Context.getQualifiedTemplateName(SS.getScopeRep(), /*TemplateKeyword=*/false, TD); else Template = TemplateName(TD); } - + if (IsFunctionTemplate) { // Function templates always go through overload resolution, at which // point we'll perform the various checks (e.g., accessibility) we need // to based on which function we selected. Result.suppressDiagnostics(); - + return NameClassification::FunctionTemplate(Template); } @@ -986,17 +986,17 @@ dyn_cast(FirstDecl)) Class = Alias->getClassInterface(); } - + if (Class) { DiagnoseUseOfDecl(Class, NameLoc); - + if (NextToken.is(tok::period)) { // Interface. is parsed as a property reference expression. // Just return "unknown" as a fall-through for now. Result.suppressDiagnostics(); return NameClassification::Unknown(); } - + QualType T = Context.getObjCInterfaceType(Class); return ParsedType::make(T); } @@ -1020,7 +1020,7 @@ return buildNestedType(*this, SS, T, NameLoc); return ParsedType::make(T); } - + if (FirstDecl->isCXXClassMember()) return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, nullptr, S); @@ -1037,15 +1037,15 @@ // Functions defined inline within classes aren't parsed until we've // finished parsing the top-level class, so the top-level class is // the context we'll need to return to. - // A Lambda call operator whose parent is a class must not be treated + // A Lambda call operator whose parent is a class must not be treated // as an inline member function. A Lambda can be used legally // either as an in-class member initializer or a default argument. These // are parsed once the class has been marked complete and so the containing // context would be the nested class (when the lambda is defined in one); - // If the class is not complete, then the lambda is being used in an + // If the class is not complete, then the lambda is being used in an // ill-formed fashion (such as to specify the width of a bit-field, or - // in an array-bound) - in which case we still want to return the - // lexically containing DC (which could be a nested class). + // in an array-bound) - in which case we still want to return the + // lexically containing DC (which could be a nested class). if (isa(DC) && !isLambdaCallOperator(DC)) { DC = DC->getLexicalParent(); @@ -1225,7 +1225,7 @@ cast(D)->isFunctionTemplateSpecialization()) return; - // If this replaces anything in the current scope, + // If this replaces anything in the current scope, IdentifierResolver::iterator I = IdResolver.begin(D->getDeclName()), IEnd = IdResolver.end(); for (; I != IEnd; ++I) { @@ -1239,7 +1239,7 @@ } S->AddDecl(D); - + if (isa(D) && !cast(D)->isGnuLocal()) { // Implicitly-generated labels may end up getting generated in an order that // isn't strictly lexical, which breaks name lookup. Be careful to insert @@ -1252,7 +1252,7 @@ } else if (IDC->Encloses(CurContext)) break; } - + IdResolver.InsertDeclAfter(I, D); } else { IdResolver.AddDecl(D); @@ -1468,7 +1468,7 @@ if (isa(D)) return true; - + // White-list anything that isn't a local variable. if (!isa(D) || isa(D) || isa(D)) return false; @@ -1486,7 +1486,7 @@ } // If we failed to complete the type for some reason, or if the type is - // dependent, don't diagnose the variable. + // dependent, don't diagnose the variable. if (Ty->isIncompleteType() || Ty->isDependentType()) return false; @@ -1516,7 +1516,7 @@ // TODO: __attribute__((unused)) templates? } - + return true; } @@ -1556,7 +1556,7 @@ UnusedLocalTypedefNameCandidates.insert(TD); return; } - + FixItHint Hint; GenerateFixForUnusedDecl(D, Context, Hint); @@ -1606,11 +1606,11 @@ if (const auto *RD = dyn_cast(D)) DiagnoseUnusedNestedTypedefs(RD); } - + // If this was a forward reference to a label, verify it was defined. if (LabelDecl *LD = dyn_cast(D)) CheckPoppedLabel(LD, *this); - + // Remove this name from our lexical scope. IdResolver.RemoveDecl(D); } @@ -1695,7 +1695,7 @@ if (!II->isStr("objc_msgSendSuper")) return; ASTContext &Context = ThisSema.Context; - + LookupResult Result(ThisSema, &Context.Idents.get("objc_super"), SourceLocation(), Sema::LookupTagName); ThisSema.LookupName(Result, S); @@ -1856,13 +1856,13 @@ if (Old->getLocation().isValid()) Diag(Old->getLocation(), diag::note_previous_definition); New->setInvalidDecl(); - return true; + return true; } - + if (OldType != NewType && !OldType->isDependentType() && !NewType->isDependentType() && - !Context.hasSameType(OldType, NewType)) { + !Context.hasSameType(OldType, NewType)) { int Kind = isa(Old) ? 1 : 0; Diag(New->getLocation(), diag::err_redefinition_different_typedef) << Kind << NewType << OldType; @@ -2001,7 +2001,7 @@ return; // C++0x [dcl.typedef]p4: - // In a given class scope, a typedef specifier can be used to redefine + // In a given class scope, a typedef specifier can be used to redefine // any class-name declared in that scope that is not also a typedef-name // to refer to the type to which it already refers. // @@ -2033,7 +2033,7 @@ // Modules always permit redefinition of typedefs, as does C11. if (getLangOpts().Modules || getLangOpts().C11) return; - + // If we have a redefinition of a typedef in C, emit a warning. This warning // is normally mapped to an error, but can be controlled with // -Wtypedef-redefinition. If either the original or the redefinition is @@ -2343,7 +2343,7 @@ ++I; continue; } else if (const AlignedAttr *AA = dyn_cast(NewAttribute)) { - if (AA->isAlignas()) { + if (AA->isAlignas()) { // C++11 [dcl.align]p6: // if any declaration of an entity has an alignment-specifier, // every defining declaration of that entity shall specify an @@ -2821,11 +2821,11 @@ Diag(OldLocation, diag::note_previous_declaration); return true; } - + NewTypeInfo = NewTypeInfo.withProducesResult(true); RequiresAdjustment = true; } - + if (RequiresAdjustment) { const FunctionType *AdjustedType = New->getType()->getAs(); AdjustedType = Context.adjustFunctionType(AdjustedType, NewTypeInfo); @@ -2978,7 +2978,7 @@ NewMethod->setImplicit(); } else { Diag(NewMethod->getLocation(), - diag::err_definition_of_implicitly_declared_member) + diag::err_definition_of_implicitly_declared_member) << New << getSpecialMember(OldMethod); return true; } @@ -3460,17 +3460,17 @@ // C++ [class.mem]p1: // A member shall not be declared twice in the member-specification [...] - // + // // Here, we need only consider static data members. if (Old->isStaticDataMember() && !New->isOutOfLine()) { - Diag(New->getLocation(), diag::err_duplicate_member) + Diag(New->getLocation(), diag::err_duplicate_member) << New->getIdentifier(); Diag(Old->getLocation(), diag::note_previous_declaration); New->setInvalidDecl(); } - + mergeDeclAttributes(New, Old); - // Warn if an already-declared variable is made a weak_import in a subsequent + // Warn if an already-declared variable is made a weak_import in a subsequent // declaration if (New->hasAttr() && Old->getStorageClass() == SC_None && @@ -4189,7 +4189,7 @@ cast(Owner)->getDeclName()))) { Diag(Record->getLocation(), diag::err_anonymous_union_not_static) << FixItHint::CreateInsertion(Record->getLocation(), "static "); - + // Recover by adding 'static'. DS.SetStorageClassSpec(*this, DeclSpec::SCS_static, SourceLocation(), PrevSpec, DiagID, Policy); @@ -4202,9 +4202,9 @@ Diag(DS.getStorageClassSpecLoc(), diag::err_anonymous_union_with_storage_spec) << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); - + // Recover by removing the storage specifier. - DS.SetStorageClassSpec(*this, DeclSpec::SCS_unspecified, + DS.SetStorageClassSpec(*this, DeclSpec::SCS_unspecified, SourceLocation(), PrevSpec, DiagID, Context.getPrintingPolicy()); } @@ -4300,7 +4300,7 @@ DK = diag::err_anonymous_record_with_function; else if (isa(Mem)) DK = diag::err_anonymous_record_with_static; - + // Visual C++ allows type definition in anonymous struct or union. if (getLangOpts().MicrosoftExt && DK == diag::err_anonymous_record_with_type) @@ -4707,7 +4707,7 @@ } /// DiagnoseClassNameShadow - Implement C++ [class.mem]p13: -/// If T is the name of a class, then each of the following shall have a +/// If T is the name of a class, then each of the following shall have a /// name different from T: /// - every static data member of class T; /// - every member function of class T @@ -4728,12 +4728,12 @@ return false; } -/// \brief Diagnose a declaration whose declarator-id has the given +/// \brief Diagnose a declaration whose declarator-id has the given /// nested-name-specifier. /// /// \param SS The nested-name-specifier of the declarator-id. /// -/// \param DC The declaration context to which the nested-name-specifier +/// \param DC The declaration context to which the nested-name-specifier /// resolves. /// /// \param Name The name of the entity being declared. @@ -4779,15 +4779,15 @@ Diag(Loc, diag::err_invalid_declarator_global_scope) << Name << SS.getRange(); else if (isa(Cur)) - Diag(Loc, diag::err_invalid_declarator_in_function) + Diag(Loc, diag::err_invalid_declarator_in_function) << Name << SS.getRange(); else if (isa(Cur)) - Diag(Loc, diag::err_invalid_declarator_in_block) + Diag(Loc, diag::err_invalid_declarator_in_block) << Name << SS.getRange(); else Diag(Loc, diag::err_invalid_declarator_scope) << Name << cast(Cur) << cast(DC) << SS.getRange(); - + return true; } @@ -4796,7 +4796,7 @@ Diag(Loc, diag::err_member_qualification) << Name << SS.getRange(); SS.clear(); - + // C++ constructors and destructors with incorrect scopes can break // our AST invariants by having the wrong underlying types. If // that's the case, then drop this declaration entirely. @@ -4805,10 +4805,10 @@ !Context.hasSameType(Name.getCXXNameType(), Context.getTypeDeclType(cast(Cur)))) return true; - + return false; } - + // C++11 [dcl.meaning]p1: // [...] "The nested-name-specifier of the qualified declarator-id shall // not begin with a decltype-specifer" @@ -4850,7 +4850,7 @@ if (D.getCXXScopeSpec().isInvalid()) D.setInvalidType(); else if (D.getCXXScopeSpec().isSet()) { - if (DiagnoseUnexpandedParameterPack(D.getCXXScopeSpec(), + if (DiagnoseUnexpandedParameterPack(D.getCXXScopeSpec(), UPPC_DeclarationQualifier)) return nullptr; @@ -4869,7 +4869,7 @@ } bool IsDependentContext = DC->isDependentContext(); - if (!IsDependentContext && + if (!IsDependentContext && RequireCompleteDeclContext(D.getCXXScopeSpec(), DC)) return nullptr; @@ -4949,11 +4949,11 @@ LookupQualifiedName(Previous, DC); // C++ [dcl.meaning]p1: - // When the declarator-id is qualified, the declaration shall refer to a - // previously declared member of the class or namespace to which the + // When the declarator-id is qualified, the declaration shall refer to a + // previously declared member of the class or namespace to which the // qualifier refers (or, in the case of a namespace, of an element of the // inline namespace set of that namespace (7.3.1)) or to a specialization - // thereof; [...] + // thereof; [...] // // Note that we already checked the context above, and that we do not have // enough information to make sure that Previous contains the declaration @@ -4969,10 +4969,10 @@ // In this case, Previous will point to the overload set // containing the two f's declared in X, but neither of them // matches. - + // C++ [dcl.meaning]p1: - // [...] the member shall not merely have been introduced by a - // using-declaration in the scope of the class or namespace nominated by + // [...] the member shall not merely have been introduced by a + // using-declaration in the scope of the class or namespace nominated by // the nested-name-specifier of the declarator-id. RemoveUsingDecls(Previous); } @@ -5040,7 +5040,7 @@ if (!New) return nullptr; - // If this has an identifier and is not an invalid redeclaration or + // If this has an identifier and is not an invalid redeclaration or // function template specialization, add it to the scope stack. if (New->getDeclName() && AddToScope && !(D.isRedeclaration() && New->isInvalidDecl())) { @@ -5072,10 +5072,10 @@ // constant expression folding, like struct {char x[(int)(char*)2];} SizeIsNegative = false; Oversized = 0; - + if (T->isDependentType()) return QualType(); - + QualifierCollector Qs; const Type *Ty = Qs.strip(T); @@ -5124,7 +5124,7 @@ Oversized = Res; return QualType(); } - + return Context.getConstantArrayType(VLATy->getElementType(), Res, ArrayType::Normal, 0); } @@ -5289,7 +5289,7 @@ else if (T->isVariableArrayType()) Diag(NewTD->getLocation(), diag::err_vla_decl_in_file_scope); else if (Oversized.getBoolValue()) - Diag(NewTD->getLocation(), diag::err_array_too_large) + Diag(NewTD->getLocation(), diag::err_array_too_large) << Oversized.toString(10); else Diag(NewTD->getLocation(), diag::err_vm_decl_in_file_scope); @@ -5370,12 +5370,12 @@ if (!OuterContext->isFunctionOrMethod()) // This rule only applies to block-scope declarations. return false; - + DeclContext *PrevOuterContext = PrevDecl->getDeclContext(); if (PrevOuterContext->isRecord()) // We found a member function: ignore it. return false; - + // Find the innermost enclosing namespace for the new and // previous declarations. OuterContext = OuterContext->getEnclosingNamespaceContext(); @@ -5426,7 +5426,7 @@ type = Context.getLifetimeQualifiedType(type, lifetime); decl->setType(type); } - + if (VarDecl *var = dyn_cast(decl)) { // Thread-local variables cannot have lifetime. if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone && @@ -5436,7 +5436,7 @@ return true; } } - + return false; } @@ -5905,7 +5905,7 @@ case SC_PrivateExtern: llvm_unreachable("C storage class in c++!"); } - } + } if (SC == SC_Static && CurContext->isRecord()) { if (const CXXRecordDecl *RD = dyn_cast(DC)) { @@ -6438,7 +6438,7 @@ // TODO: should we warn about static data members shadowing // static data members from base classes? - + // TODO: don't diagnose for inaccessible shadowed members. // This is hard to do perfectly because we might friend the // shadowing context, but that's just a false negative. @@ -6729,7 +6729,7 @@ Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local); } } - + bool isVM = T->isVariablyModifiedType(); if (isVM || NewVD->hasAttr() || NewVD->hasAttr()) @@ -7196,9 +7196,9 @@ (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) || (!isa(R.getTypePtr()) && R->isFunctionProtoType()); - NewFD = FunctionDecl::Create(SemaRef.Context, DC, - D.getLocStart(), NameInfo, R, - TInfo, SC, isInline, + NewFD = FunctionDecl::Create(SemaRef.Context, DC, + D.getLocStart(), NameInfo, R, + TInfo, SC, isInline, HasPrototype, false); if (D.isInvalidType()) NewFD->setInvalidDecl(); @@ -7607,8 +7607,8 @@ Diag(NewFD->getLocation(), diag::err_destructor_template); NewFD->setInvalidDecl(); } - - // If we're adding a template to a dependent context, we may need to + + // If we're adding a template to a dependent context, we may need to // rebuilding some of the types used within the template parameter list, // now that we know what the current instantiation is. if (DC->isDependentContext()) { @@ -7616,7 +7616,7 @@ if (RebuildTemplateParamsInCurrentInstantiation(TemplateParams)) Invalid = true; } - + FunctionTemplate = FunctionTemplateDecl::Create(Context, DC, NewFD->getLocation(), Name, TemplateParams, @@ -7684,7 +7684,7 @@ diag::err_virtual_non_function); } else if (!CurContext->isRecord()) { // 'virtual' was specified outside of the class. - Diag(D.getDeclSpec().getVirtualSpecLoc(), + Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_virtual_out_of_class) << FixItHint::CreateRemoval(D.getDeclSpec().getVirtualSpecLoc()); } else if (NewFD->getDescribedFunctionTemplate()) { @@ -7722,12 +7722,12 @@ } // C++ [dcl.fct.spec]p3: - // The inline specifier shall not appear on a block scope function + // The inline specifier shall not appear on a block scope function // declaration. if (isInline && !NewFD->isInvalidDecl()) { if (CurContext->isFunctionOrMethod()) { // 'inline' is not allowed on block scope function declaration. - Diag(D.getDeclSpec().getInlineSpecLoc(), + Diag(D.getDeclSpec().getInlineSpecLoc(), diag::err_inline_declaration_block_scope) << Name << FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc()); } @@ -7735,22 +7735,22 @@ // C++ [dcl.fct.spec]p6: // The explicit specifier shall be used only in the declaration of a - // constructor or conversion function within its class definition; + // constructor or conversion function within its class definition; // see 12.3.1 and 12.3.2. if (isExplicit && !NewFD->isInvalidDecl()) { if (!CurContext->isRecord()) { // 'explicit' was specified outside of the class. - Diag(D.getDeclSpec().getExplicitSpecLoc(), + Diag(D.getDeclSpec().getExplicitSpecLoc(), diag::err_explicit_out_of_class) << FixItHint::CreateRemoval(D.getDeclSpec().getExplicitSpecLoc()); - } else if (!isa(NewFD) && + } else if (!isa(NewFD) && !isa(NewFD)) { // 'explicit' was specified on a function that wasn't a constructor // or conversion function. Diag(D.getDeclSpec().getExplicitSpecLoc(), diag::err_explicit_non_ctor_or_conv_function) << FixItHint::CreateRemoval(D.getDeclSpec().getExplicitSpecLoc()); - } + } } if (isConstexpr) { @@ -7879,11 +7879,11 @@ case FDK_Declaration: case FDK_Definition: break; - + case FDK_Defaulted: NewFD->setDefaulted(); break; - + case FDK_Deleted: NewFD->setDeletedAsWritten(); break; @@ -7892,7 +7892,7 @@ if (isa(NewFD) && DC == CurContext && D.isFunctionDefinition()) { // C++ [class.mfct]p2: - // A member function may be defined (8.4) in its class definition, in + // A member function may be defined (8.4) in its class definition, in // which case it is an inline member function (7.1.2) NewFD->setImplicitlyInline(); } @@ -8099,7 +8099,7 @@ diag::ext_operator_new_delete_declared_inline) << NewFD->getDeclName(); - // If the declarator is a template-id, translate the parser's template + // If the declarator is a template-id, translate the parser's template // argument list into our AST format. if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { TemplateIdAnnotation *TemplateId = D.getName().TemplateId; @@ -8155,10 +8155,10 @@ Previous)) NewFD->setInvalidDecl(); } else if (isFunctionTemplateSpecialization) { - if (CurContext->isDependentContext() && CurContext->isRecord() + if (CurContext->isDependentContext() && CurContext->isRecord() && !isFriend) { isDependentClassScopeExplicitSpecialization = true; - Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ? + Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ? diag::ext_function_specialization_in_class : diag::err_function_specialization_in_class) << NewFD->getDeclName(); @@ -8167,7 +8167,7 @@ : nullptr), Previous)) NewFD->setInvalidDecl(); - + // C++ [dcl.stc]p1: // A storage-class-specifier shall not be specified in an explicit // specialization (14.7.3) @@ -8180,9 +8180,9 @@ << SC << FixItHint::CreateRemoval( D.getDeclSpec().getStorageClassSpecLoc()); - + else - Diag(NewFD->getLocation(), + Diag(NewFD->getLocation(), diag::ext_explicit_specialization_storage_class) << FixItHint::CreateRemoval( D.getDeclSpec().getStorageClassSpecLoc()); @@ -8232,7 +8232,7 @@ // If we have a function template, check the template parameter // list. This will check and merge default template arguments. if (FunctionTemplate) { - FunctionTemplateDecl *PrevTemplate = + FunctionTemplateDecl *PrevTemplate = FunctionTemplate->getPreviousDecl(); CheckTemplateParameterList(FunctionTemplate->getTemplateParameters(), PrevTemplate ? PrevTemplate->getTemplateParameters() @@ -8241,8 +8241,8 @@ ? (D.isFunctionDefinition() ? TPC_FriendFunctionTemplateDefinition : TPC_FriendFunctionTemplate) - : (D.getCXXScopeSpec().isSet() && - DC && DC->isRecord() && + : (D.getCXXScopeSpec().isSet() && + DC && DC->isRecord() && DC->isDependentContext()) ? TPC_ClassTemplateMember : TPC_FunctionTemplate); @@ -8313,8 +8313,8 @@ // definition (C++ [class.mfct]p2). // Note that this is not the case for explicit specializations of // function templates or member functions of class templates, per - // C++ [temp.expl.spec]p2. We also allow these declarations as an - // extension for compatibility with old SWIG code which likes to + // C++ [temp.expl.spec]p2. We also allow these declarations as an + // extension for compatibility with old SWIG code which likes to // generate them. Diag(NewFD->getLocation(), diag::ext_out_of_line_declaration) << D.getCXXScopeSpec().getRange(); @@ -8326,7 +8326,7 @@ AddKnownFunctionAttributes(NewFD); - if (NewFD->hasAttr() && + if (NewFD->hasAttr() && !NewFD->getType()->getAs()) { Diag(NewFD->getLocation(), diag::err_attribute_overloadable_no_prototype) @@ -8409,7 +8409,7 @@ Diag(D.getIdentifierLoc(), diag::err_static_kernel); D.setInvalidType(); } - + // OpenCL v1.2, s6.9 -- Kernels can only have return type void. if (!NewFD->getReturnType()->isVoidType()) { SourceRange RTRange = NewFD->getReturnTypeSourceRange(); @@ -8449,7 +8449,7 @@ if (isDependentClassScopeExplicitSpecialization) { ClassScopeFunctionSpecializationDecl *NewSpec = ClassScopeFunctionSpecializationDecl::Create( - Context, CurContext, SourceLocation(), + Context, CurContext, SourceLocation(), cast(NewFD), HasExplicitTemplateArgs, TemplateArgs); CurContext->addDecl(NewSpec); @@ -8619,20 +8619,20 @@ FunctionTemplateDecl *NewTemplateDecl = NewFD->getDescribedFunctionTemplate(); assert(NewTemplateDecl && "Template/non-template mismatch"); - if (CXXMethodDecl *Method + if (CXXMethodDecl *Method = dyn_cast(NewTemplateDecl->getTemplatedDecl())) { Method->setAccess(OldTemplateDecl->getAccess()); NewTemplateDecl->setAccess(OldTemplateDecl->getAccess()); } - + // If this is an explicit specialization of a member that is a function // template, mark it as a member specialization. - if (IsExplicitSpecialization && + if (IsExplicitSpecialization && NewTemplateDecl->getInstantiatedFromMemberTemplate()) { NewTemplateDecl->setMemberSpecialization(); assert(OldTemplateDecl->isMemberSpecialization()); } - + } else { // This needs to happen first so that 'inline' propagates. NewFD->setPreviousDeclaration(cast(OldDecl)); @@ -8648,11 +8648,11 @@ // C++-specific checks. if (CXXConstructorDecl *Constructor = dyn_cast(NewFD)) { CheckConstructor(Constructor); - } else if (CXXDestructorDecl *Destructor = + } else if (CXXDestructorDecl *Destructor = dyn_cast(NewFD)) { CXXRecordDecl *Record = Destructor->getParent(); QualType ClassType = Context.getTypeDeclType(Record); - + // FIXME: Shouldn't we be able to perform this check even when the class // type is dependent? Both gcc and edg can handle that. if (!ClassType->isDependentType()) { @@ -8672,7 +8672,7 @@ // Find any virtual functions that this function overrides. if (CXXMethodDecl *Method = dyn_cast(NewFD)) { - if (!Method->isFunctionTemplateSpecialization() && + if (!Method->isFunctionTemplateSpecialization() && !Method->getDescribedFunctionTemplate() && Method->isCanonicalDecl()) { if (AddOverriddenMethods(Method->getParent(), Method)) { @@ -8682,7 +8682,7 @@ } } } - + if (Method->isStatic()) checkThisInStaticMemberFunctionType(Method); } @@ -8708,7 +8708,7 @@ CheckCXXDefaultArguments(NewFD); // If this function declares a builtin function, check the type of this - // declaration against the expected type for the builtin. + // declaration against the expected type for the builtin. if (unsigned BuiltinID = NewFD->getBuiltinID()) { ASTContext::GetBuiltinTypeError Error; LookupPredefedObjCSuperType(*this, S, NewFD->getIdentifier()); @@ -8720,7 +8720,7 @@ } } - // If this function is declared as being extern "C", then check to see if + // If this function is declared as being extern "C", then check to see if // the function returns a UDT (class, struct, or union type) that is not C // compatible, and if it does, warn the user. // But, issue any diagnostic on the first declaration only. @@ -8746,11 +8746,11 @@ // static main is not an error under C99, but we should warn about it. // We accept _Noreturn main as an extension. if (FD->getStorageClass() == SC_Static) - Diag(DS.getStorageClassSpecLoc(), getLangOpts().CPlusPlus - ? diag::err_static_main : diag::warn_static_main) + Diag(DS.getStorageClassSpecLoc(), getLangOpts().CPlusPlus + ? diag::err_static_main : diag::warn_static_main) << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); if (FD->isInlineSpecified()) - Diag(DS.getInlineSpecLoc(), diag::err_inline_main) + Diag(DS.getInlineSpecLoc(), diag::err_inline_main) << FixItHint::CreateRemoval(DS.getInlineSpecLoc()); if (DS.isNoreturnSpecified()) { SourceLocation NoreturnLoc = DS.getNoreturnSpecLoc(); @@ -8877,7 +8877,7 @@ if (nparams == 1 && !FD->isInvalidDecl()) { Diag(FD->getLocation(), diag::warn_main_one_arg); } - + if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) { Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD; FD->setInvalidDecl(); @@ -9450,7 +9450,7 @@ VarDecl *Def; if ((Def = VDecl->getDefinition()) && Def != VDecl) { NamedDecl *Hidden = nullptr; - if (!hasVisibleDefinition(Def, &Hidden) && + if (!hasVisibleDefinition(Def, &Hidden) && (VDecl->getFormalLinkage() == InternalLinkage || VDecl->getDescribedVarTemplate() || VDecl->getNumTemplateParameterLists() || @@ -9486,7 +9486,7 @@ diag::note_previous_initializer) << 0; return; - } + } if (VDecl->hasLocalStorage()) getCurFunction()->setHasBranchProtectedScope(); @@ -9508,7 +9508,7 @@ // Get the decls type and save a reference for later, since // CheckInitializerTypes may change it. QualType DclT = VDecl->getType(), SavT = DclT; - + // Expressions default to 'id' when we're in a debugger // and we are assigning it to a variable of Objective-C pointer type. if (getLangOpts().DebuggerCastResultToId && DclT->isObjCObjectPointerType() && @@ -9799,7 +9799,7 @@ if (Ty->isDependentType()) return; // Require a complete type. - if (RequireCompleteType(VD->getLocation(), + if (RequireCompleteType(VD->getLocation(), Context.getBaseElementType(Ty), diag::err_typecheck_decl_incomplete_type)) { VD->setInvalidDecl(); @@ -9880,17 +9880,17 @@ // We have an out-of-line definition of a static data member // that has an in-class initializer, so we type-check this like - // a declaration. + // a declaration. // // Fall through - + case VarDecl::DeclarationOnly: - // It's only a declaration. + // It's only a declaration. // Block scope. C99 6.7p7: If an identifier for an object is // declared with no linkage (C99 6.2.2p6), the type for the // object shall be complete. - if (!Type->isDependentType() && Var->isLocalVarDecl() && + if (!Type->isDependentType() && Var->isLocalVarDecl() && !Var->hasLinkage() && !Var->isInvalidDecl() && RequireCompleteType(Var->getLocation(), Type, diag::err_typecheck_decl_incomplete_type)) @@ -9907,7 +9907,7 @@ Diag(Var->getLocation(), diag::warn_private_extern); Diag(Var->getLocation(), diag::note_private_extern); } - + return; case VarDecl::TentativeDefinition: @@ -10012,7 +10012,7 @@ getCurFunction()->setHasBranchProtectedScope(); } } - + // C++03 [dcl.init]p9: // If no initializer is specified for an object, and the // object is of (possibly cv-qualified) non-POD class type (or @@ -10638,7 +10638,7 @@ // Check that there are no default arguments inside the type of this // parameter. CheckExtraCXXDefaultArguments(D); - + // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1). if (D.getCXXScopeSpec().isSet()) { Diag(D.getIdentifierLoc(), diag::err_qualified_param_declarator) @@ -10698,7 +10698,7 @@ assert(S->getFunctionPrototypeDepth() >= 1); New->setScopeInfo(S->getFunctionPrototypeDepth() - 1, S->getNextFunctionPrototypeIndex()); - + // Add the parameter declaration into this scope. S->AddDecl(New); if (II) @@ -10806,7 +10806,7 @@ } ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name, - Context.getAdjustedParameterType(T), + Context.getAdjustedParameterType(T), TSInfo, SC, nullptr); // Parameters can not be abstract class types. @@ -10828,7 +10828,7 @@ New->setType(T); } - // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage + // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage // duration shall not be qualified by an address-space qualifier." // Since all parameters have automatic store duration, they can not have // an address space. @@ -10907,7 +10907,7 @@ Consumer.HandleInlineFunctionDefinition(D); } -static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, +static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, const FunctionDecl*& PossibleZeroParamPrototype) { // Don't warn about invalid declarations. if (FD->isInvalidDecl()) @@ -11003,10 +11003,10 @@ FD->setInvalidDecl(); } -static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, +static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, Sema &S) { CXXRecordDecl *const LambdaClass = CallOperator->getParent(); - + LambdaScopeInfo *LSI = S.PushLambdaScope(); LSI->CallOperator = CallOperator; LSI->Lambda = LambdaClass; @@ -11020,12 +11020,12 @@ else if (LCD == LCD_ByRef) LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByref; DeclarationNameInfo DNI = CallOperator->getNameInfo(); - - LSI->IntroducerRange = DNI.getCXXOperatorNameRange(); + + LSI->IntroducerRange = DNI.getCXXOperatorNameRange(); LSI->Mutable = !CallOperator->isConst(); // Add the captures to the LSI so they can be noted as already - // captured within tryCaptureVar. + // captured within tryCaptureVar. auto I = LambdaClass->field_begin(); for (const auto &C : LambdaClass->captures()) { if (C.capturesVariable()) { @@ -11034,14 +11034,14 @@ S.CurrentInstantiationScope->InstantiatedLocal(VD, VD); QualType CaptureType = VD->getType(); const bool ByRef = C.getCaptureKind() == LCK_ByRef; - LSI->addCapture(VD, /*IsBlock*/false, ByRef, + LSI->addCapture(VD, /*IsBlock*/false, ByRef, /*RefersToEnclosingVariableOrCapture*/true, C.getLocation(), - /*EllipsisLoc*/C.isPackExpansion() + /*EllipsisLoc*/C.isPackExpansion() ? C.getEllipsisLoc() : SourceLocation(), CaptureType, /*Expr*/ nullptr); } else if (C.capturesThis()) { - LSI->addThisCapture(/*Nested*/ false, C.getLocation(), + LSI->addThisCapture(/*Nested*/ false, C.getLocation(), S.getCurrentThisType(), /*Expr*/ nullptr, C.getCaptureKind() == LCK_StarThis); } else { @@ -11055,7 +11055,7 @@ SkipBodyInfo *SkipBody) { // Clear the last template instantiation error context. LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation(); - + if (!D) return D; FunctionDecl *FD = nullptr; @@ -11076,16 +11076,16 @@ // If we are instantiating a generic lambda call operator, push // a LambdaScopeInfo onto the function stack. But use the information - // that's already been calculated (ActOnLambdaExpr) to prime the current - // LambdaScopeInfo. + // that's already been calculated (ActOnLambdaExpr) to prime the current + // LambdaScopeInfo. // When the template operator is being specialized, the LambdaScopeInfo, // has to be properly restored so that tryCaptureVariable doesn't try // and capture any new variables. In addition when calculating potential - // captures during transformation of nested lambdas, it is necessary to - // have the LSI properly restored. + // captures during transformation of nested lambdas, it is necessary to + // have the LSI properly restored. if (isGenericLambdaCallOperatorSpecialization(FD)) { assert(ActiveTemplateInstantiations.size() && - "There should be an active template instantiation on the stack " + "There should be an active template instantiation on the stack " "when instantiating a generic lambda!"); RebuildLambdaScopeInfo(cast(D), *this); } @@ -11182,15 +11182,15 @@ getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl && getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) Diag(FD->getLocation(), diag::warn_function_def_in_objc_container); - + return D; } /// \brief Given the set of return statements within a function body, -/// compute the variables that are subject to the named return value +/// compute the variables that are subject to the named return value /// optimization. /// -/// Each of the variables that is subject to the named return value +/// Each of the variables that is subject to the named return value /// optimization will be marked as NRVO variables in the AST, and any /// return statement that has a marked NRVO variable as its NRVO candidate can /// use the named return value optimization. @@ -11342,7 +11342,7 @@ MarkVTableUsed(FD->getLocation(), Constructor->getParent()); else if (CXXDestructorDecl *Destructor = dyn_cast(FD)) MarkVTableUsed(FD->getLocation(), Destructor->getParent()); - + // Try to apply the named return value optimization. We have to check // if we can do this here because lambdas keep return statements around // to deduce an implicit return type. @@ -11466,7 +11466,7 @@ // Verify this. if (FD && isa(FD) && isa(Body)) DiagnoseReturnInConstructorExceptionHandler(cast(Body)); - + // Verify that gotos and switch cases don't jump into scopes illegally. if (getCurFunction()->NeedsScopeChecking() && !PP.isCodeCompletionEnabled()) @@ -11479,7 +11479,7 @@ MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(), Destructor->getParent()); } - + // If any errors have occurred, clear out any temporaries that may have // been leftover. This ensures that these temporaries won't be picked up for // deletion in some later function. @@ -11517,7 +11517,7 @@ assert(MaybeODRUseExprs.empty() && "Leftover expressions for odr-use checking"); } - + if (!IsInstantiation) PopDeclContext(); @@ -11539,8 +11539,8 @@ // Always attach attributes to the underlying decl. if (TemplateDecl *TD = dyn_cast(D)) D = TD->getTemplatedDecl(); - ProcessDeclAttributeList(S, D, Attrs.getList()); - + ProcessDeclAttributeList(S, D, Attrs.getList()); + if (CXXMethodDecl *Method = dyn_cast_or_null(D)) if (Method->isStatic()) checkThisInStaticMemberFunctionAttributes(Method); @@ -11692,6 +11692,8 @@ FD->getLocation())); if (Context.BuiltinInfo.isNoThrow(BuiltinID) && !FD->hasAttr()) FD->addAttr(NoThrowAttr::CreateImplicit(Context, FD->getLocation())); + if (Context.BuiltinInfo.isPure(BuiltinID) && !FD->hasAttr()) + FD->addAttr(PureAttr::CreateImplicit(Context, FD->getLocation())); if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->hasAttr()) FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation())); if (getLangOpts().CUDA && Context.BuiltinInfo.isTSBuiltin(BuiltinID) && @@ -11771,7 +11773,7 @@ NewTD->setInvalidDecl(); return NewTD; } - + if (D.getDeclSpec().isModulePrivateSpecified()) { if (CurContext->isFunctionOrMethod()) Diag(NewTD->getLocation(), diag::err_module_private_local) @@ -11781,7 +11783,7 @@ else NewTD->setModulePrivate(); } - + // C++ [dcl.typedef]p8: // If the typedef declaration defines an unnamed class (or // enum), the first typedef-name declared by the declaration @@ -12233,7 +12235,7 @@ } // A tag 'foo::bar' must already exist. - Diag(NameLoc, diag::err_not_tag_in_scope) + Diag(NameLoc, diag::err_not_tag_in_scope) << Kind << Name << DC << SS.getRange(); Name = nullptr; Invalid = true; @@ -12257,7 +12259,7 @@ // When declaring or defining a tag, ignore ambiguities introduced // by types using'ed into this scope. - if (Previous.isAmbiguous() && + if (Previous.isAmbiguous() && (TUK == TUK_Definition || TUK == TUK_Declaration)) { LookupResult::Filter F = Previous.makeFilter(); while (F.hasNext()) { @@ -12333,10 +12335,10 @@ DC->Equals(getStdNamespace()) && Name->isStr("bad_alloc")) { // This is a declaration of or a reference to "std::bad_alloc". isStdBadAlloc = true; - + if (Previous.empty() && StdBadAlloc) { // std::bad_alloc has been implicitly declared (but made invisible to - // name lookup). Fill in this implicit declaration as the previous + // name lookup). Fill in this implicit declaration as the previous // declaration, so that the declarations get chained appropriately. Previous.addDecl(getStdBadAlloc()); } @@ -12749,8 +12751,8 @@ else if (getLangOpts().CPlusPlus) DiagID = diag::err_forward_ref_enum; Diag(Loc, DiagID); - - // If this is a forward-declared reference to an enumeration, make a + + // If this is a forward-declared reference to an enumeration, make a // note of it; we won't actually be introducing the declaration into // the declaration context. if (TUK == TUK_Reference) @@ -12794,10 +12796,10 @@ // Maybe add qualifier info. if (SS.isNotEmpty()) { if (SS.isSet()) { - // If this is either a declaration or a definition, check the + // If this is either a declaration or a definition, check the // nested-name-specifier against the current context. We don't do this // for explicit specializations, because they have similar checking - // (with more specific diagnostics) in the call to + // (with more specific diagnostics) in the call to // CheckMemberSpecialization, below. if (!isExplicitSpecialization && (TUK == TUK_Definition || TUK == TUK_Declaration) && @@ -12933,7 +12935,7 @@ void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) { AdjustDeclIfTemplate(TagD); TagDecl *Tag = cast(TagD); - + // Enter the tag context. PushDeclContext(S, Tag); @@ -12945,7 +12947,7 @@ } Decl *Sema::ActOnObjCContainerStartDefinition(Decl *IDecl) { - assert(isa(IDecl) && + assert(isa(IDecl) && "ActOnObjCContainerStartDefinition - Not ObjCContainerDecl"); DeclContext *OCD = cast(IDecl); assert(getContainingDC(OCD) == CurContext && @@ -13050,7 +13052,7 @@ // ActOnStartCXXMemberDeclarations, so we don't have to mess with // the FieldCollector. - PopDeclContext(); + PopDeclContext(); } // Note that FieldName may be null for anonymous bitfields. @@ -13209,11 +13211,11 @@ case LookupResult::FoundUnresolvedValue: PrevDecl = Previous.getAsSingle(); break; - + case LookupResult::FoundOverloaded: PrevDecl = Previous.getRepresentativeDecl(); break; - + case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: case LookupResult::Ambiguous: @@ -13243,7 +13245,7 @@ if (D.getDeclSpec().isModulePrivateSpecified()) NewFD->setModulePrivate(); - + if (NewFD->isInvalidDecl() && PrevDecl) { // Don't introduce NewFD into scope; there's already something // with the same name in the same scope. @@ -13475,9 +13477,9 @@ if (!getLangOpts().CPlusPlus11 && getLangOpts().ObjCAutoRefCount && RDecl->hasObjectMember()) { // Objective-C++ ARC: it is an error to have a non-trivial field of - // a union. However, system headers in Objective-C programs + // a union. However, system headers in Objective-C programs // occasionally have Objective-C lifetime objects within unions, - // and rather than cause the program to fail, we make those + // and rather than cause the program to fail, we make those // members unavailable. SourceLocation Loc = FD->getLocation(); if (getSourceManager().isInSystemHeader(Loc)) { @@ -13573,7 +13575,7 @@ else EnclosingContext = EnclosingDecl; } else { - if (ObjCCategoryDecl *CDecl = + if (ObjCCategoryDecl *CDecl = dyn_cast(EnclosingDecl)) { if (LangOpts.ObjCRuntime.isFragile() || !CDecl->IsClassExtension()) { Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension(); @@ -13611,33 +13613,33 @@ if (D.getDeclSpec().isModulePrivateSpecified()) NewID->setModulePrivate(); - + if (II) { // FIXME: When interfaces are DeclContexts, we'll need to add // these to the interface. S->AddDecl(NewID); IdResolver.AddDecl(NewID); } - + if (LangOpts.ObjCRuntime.isNonFragile() && !NewID->isInvalidDecl() && isa(EnclosingDecl)) Diag(Loc, diag::warn_ivars_in_interface); - + return NewID; } -/// ActOnLastBitfield - This routine handles synthesized bitfields rules for -/// class and class extensions. For every class \@interface and class -/// extension \@interface, if the last ivar is a bitfield of any type, +/// ActOnLastBitfield - This routine handles synthesized bitfields rules for +/// class and class extensions. For every class \@interface and class +/// extension \@interface, if the last ivar is a bitfield of any type, /// then add an implicit `char :0` ivar to the end of that interface. void Sema::ActOnLastBitfield(SourceLocation DeclLoc, SmallVectorImpl &AllIvarDecls) { if (LangOpts.ObjCRuntime.isFragile() || AllIvarDecls.empty()) return; - + Decl *ivarDecl = AllIvarDecls[AllIvarDecls.size()-1]; ObjCIvarDecl *Ivar = cast(ivarDecl); - + if (!Ivar->isBitField() || Ivar->getBitWidthValue(Context) == 0) return; ObjCInterfaceDecl *ID = dyn_cast(CurContext); @@ -13656,7 +13658,7 @@ Ivar = ObjCIvarDecl::Create(Context, cast(CurContext), DeclLoc, DeclLoc, nullptr, - Context.CharTy, + Context.CharTy, Context.getTrivialTypeSourceInfo(Context.CharTy, DeclLoc), ObjCIvarDecl::Private, BW, @@ -13685,7 +13687,7 @@ break; } } - + RecordDecl *Record = dyn_cast(EnclosingDecl); // Start counting up the number of named members; make sure to include @@ -13739,7 +13741,7 @@ FD->setInvalidDecl(); EnclosingDecl->setInvalidDecl(); continue; - } else if (FDTy->isIncompleteArrayType() && Record && + } else if (FDTy->isIncompleteArrayType() && Record && ((i + 1 == Fields.end() && !Record->isUnion()) || ((getLangOpts().MicrosoftExt || getLangOpts().CPlusPlus) && @@ -13856,7 +13858,7 @@ UnavailableAttr::IR_ARCFieldWithOwnership, loc)); } } else { - Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag) + Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag) << T->isBlockPointerType() << Record->getTagKind(); } ARCErrReported = true; @@ -13869,7 +13871,7 @@ Record->setHasObjectMember(true); else if (Context.getAsArrayType(FD->getType())) { QualType BaseType = Context.getBaseElementType(FD->getType()); - if (BaseType->isRecordType() && + if (BaseType->isRecordType() && BaseType->getAs()->getDecl()->hasObjectMember()) Record->setHasObjectMember(true); else if (BaseType->isObjCObjectPointerType() || @@ -13908,39 +13910,39 @@ // Add any implicitly-declared members to this class. AddImplicitlyDeclaredMembersToClass(CXXRecord); - // If we have virtual base classes, we may end up finding multiple - // final overriders for a given virtual function. Check for this + // If we have virtual base classes, we may end up finding multiple + // final overriders for a given virtual function. Check for this // problem now. if (CXXRecord->getNumVBases()) { CXXFinalOverriderMap FinalOverriders; CXXRecord->getFinalOverriders(FinalOverriders); - - for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(), + + for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(), MEnd = FinalOverriders.end(); M != MEnd; ++M) { - for (OverridingMethods::iterator SO = M->second.begin(), + for (OverridingMethods::iterator SO = M->second.begin(), SOEnd = M->second.end(); SO != SOEnd; ++SO) { - assert(SO->second.size() > 0 && + assert(SO->second.size() > 0 && "Virtual function without overridding functions?"); if (SO->second.size() == 1) continue; - + // C++ [class.virtual]p2: // In a derived class, if a virtual member function of a base // class subobject has more than one final overrider the // program is ill-formed. Diag(Record->getLocation(), diag::err_multiple_final_overriders) << (const NamedDecl *)M->first << Record; - Diag(M->first->getLocation(), + Diag(M->first->getLocation(), diag::note_overridden_virtual_function); - for (OverridingMethods::overriding_iterator - OM = SO->second.begin(), + for (OverridingMethods::overriding_iterator + OM = SO->second.begin(), OMEnd = SO->second.end(); OM != OMEnd; ++OM) Diag(OM->Method->getLocation(), diag::note_final_overrider) << (const NamedDecl *)M->first << OM->Method->getParent(); - + Record->setInvalidDecl(); } } @@ -13950,7 +13952,7 @@ } } } - + if (!Completed) Record->completeDefinition(); @@ -14039,7 +14041,7 @@ CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac); IMPDecl->setIvarLBraceLoc(LBrac); IMPDecl->setIvarRBraceLoc(RBrac); - } else if (ObjCCategoryDecl *CDecl = + } else if (ObjCCategoryDecl *CDecl = dyn_cast(EnclosingDecl)) { // case of ivars in class extension; all other cases have been // reported as errors elsewhere. @@ -14050,18 +14052,18 @@ ObjCInterfaceDecl *IDecl = CDecl->getClassInterface(); for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { if (IDecl) { - if (const ObjCIvarDecl *ClsIvar = + if (const ObjCIvarDecl *ClsIvar = IDecl->getIvarDecl(ClsFields[i]->getIdentifier())) { - Diag(ClsFields[i]->getLocation(), - diag::err_duplicate_ivar_declaration); + Diag(ClsFields[i]->getLocation(), + diag::err_duplicate_ivar_declaration); Diag(ClsIvar->getLocation(), diag::note_previous_definition); continue; } for (const auto *Ext : IDecl->known_extensions()) { if (const ObjCIvarDecl *ClsExtIvar = Ext->getIvarDecl(ClsFields[i]->getIdentifier())) { - Diag(ClsFields[i]->getLocation(), - diag::err_duplicate_ivar_declaration); + Diag(ClsFields[i]->getLocation(), + diag::err_duplicate_ivar_declaration); Diag(ClsExtIvar->getLocation(), diag::note_previous_definition); continue; } @@ -14086,37 +14088,37 @@ QualType T) { assert(T->isIntegralType(Context) && "Integral type required!"); unsigned BitWidth = Context.getIntWidth(T); - + if (Value.isUnsigned() || Value.isNonNegative()) { - if (T->isSignedIntegerOrEnumerationType()) + if (T->isSignedIntegerOrEnumerationType()) --BitWidth; return Value.getActiveBits() <= BitWidth; - } + } return Value.getMinSignedBits() <= BitWidth; } // \brief Given an integral type, return the next larger integral type // (or a NULL type of no such type exists). static QualType getNextLargerIntegralType(ASTContext &Context, QualType T) { - // FIXME: Int128/UInt128 support, which also needs to be introduced into + // FIXME: Int128/UInt128 support, which also needs to be introduced into // enum checking below. assert(T->isIntegralType(Context) && "Integral type required!"); const unsigned NumTypes = 4; - QualType SignedIntegralTypes[NumTypes] = { + QualType SignedIntegralTypes[NumTypes] = { Context.ShortTy, Context.IntTy, Context.LongTy, Context.LongLongTy }; - QualType UnsignedIntegralTypes[NumTypes] = { - Context.UnsignedShortTy, Context.UnsignedIntTy, Context.UnsignedLongTy, + QualType UnsignedIntegralTypes[NumTypes] = { + Context.UnsignedShortTy, Context.UnsignedIntTy, Context.UnsignedLongTy, Context.UnsignedLongLongTy }; - + unsigned BitWidth = Context.getTypeSize(T); QualType *Types = T->isSignedIntegerOrEnumerationType()? SignedIntegralTypes : UnsignedIntegralTypes; for (unsigned I = 0; I != NumTypes; ++I) if (Context.getTypeSize(Types[I]) > BitWidth) return Types[I]; - + return QualType(); } @@ -14180,7 +14182,7 @@ // C++11 [dcl.enum]p5: // If the underlying type is not fixed, the type of each enumerator // is the type of its initializing value: - // - If an initializer is specified for an enumerator, the + // - If an initializer is specified for an enumerator, the // initializing value has the same type as the expression. EltTy = Val->getType(); } else { @@ -14211,10 +14213,10 @@ // C++0x [dcl.enum]p5: // If the underlying type is not fixed, the type of each enumerator // is the type of its initializing value: - // - If no initializer is specified for the first enumerator, the + // - If no initializer is specified for the first enumerator, the // initializing value has an unspecified integral type. // - // GCC uses 'int' for its unspecified integral type, as does + // GCC uses 'int' for its unspecified integral type, as does // C99 6.7.2.2p3. if (Enum->isFixed()) { EltTy = Enum->getIntegerType(); @@ -14237,12 +14239,12 @@ // - Otherwise the type of the initializing value is the same as // the type of the initializing value of the preceding enumerator // unless the incremented value is not representable in that type, - // in which case the type is an unspecified integral type + // in which case the type is an unspecified integral type // sufficient to contain the incremented value. If no such type // exists, the program is ill-formed. QualType T = getNextLargerIntegralType(Context, EltTy); if (T.isNull() || Enum->isFixed()) { - // There is no integral type larger enough to represent this + // There is no integral type larger enough to represent this // value. Complain, then allow the value to wrap around. EnumVal = LastEnumConst->getInitVal(); EnumVal = EnumVal.zext(EnumVal.getBitWidth() * 2); @@ -14258,15 +14260,15 @@ } else { EltTy = T; } - + // Retrieve the last enumerator's value, extent that type to the // type that is supposed to be large enough to represent the incremented // value, then increment. EnumVal = LastEnumConst->getInitVal(); EnumVal.setIsSigned(EltTy->isSignedIntegerOrEnumerationType()); EnumVal = EnumVal.zextOrTrunc(Context.getIntWidth(EltTy)); - ++EnumVal; - + ++EnumVal; + // If we're not in C++, diagnose the overflow of enumerator values, // which in C99 means that the enumerator value is not representable in // an int (C99 6.7.2.2p2). However, we support GCC's extension that @@ -14284,12 +14286,12 @@ } if (!EltTy->isDependentType()) { - // Make the enumerator value match the signedness and size of the + // Make the enumerator value match the signedness and size of the // enumerator's type. EnumVal = EnumVal.extOrTrunc(Context.getIntWidth(EltTy)); EnumVal.setIsSigned(EltTy->isSignedIntegerOrEnumerationType()); } - + return EnumConstantDecl::Create(Context, Enum, IdLoc, Id, EltTy, Val, EnumVal); } @@ -14344,14 +14346,14 @@ } // C++ [class.mem]p15: - // If T is the name of a class, then each of the following shall have a name + // If T is the name of a class, then each of the following shall have a name // different from T: - // - every enumerator of every member of class T that is an unscoped + // - every enumerator of every member of class T that is an unscoped // enumerated type if (!TheEnumDecl->isScoped()) DiagnoseClassNameShadow(TheEnumDecl->getDeclContext(), DeclarationNameInfo(Id, IdLoc)); - + EnumConstantDecl *New = CheckEnumConstant(TheEnumDecl, LastEnumConst, IdLoc, Id, Val); if (!New) @@ -14660,7 +14662,7 @@ // int, long long int, or unsigned long long int. // C99 6.4.4.3p2: // An identifier declared as an enumeration constant has type int. - // The C99 rule is modified by a gcc extension + // The C99 rule is modified by a gcc extension QualType BestPromotionType; bool Packed = Enum->hasAttr(); @@ -14876,8 +14878,8 @@ return checkModuleImportContext(*this, M, ImportLoc, CurContext); } -DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, - SourceLocation ImportLoc, +DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, + SourceLocation ImportLoc, ModuleIdPath Path) { Module *Mod = getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible, @@ -14906,13 +14908,13 @@ if (!ModCheck) break; ModCheck = ModCheck->Parent; - + IdentifierLocs.push_back(Path[I].second); } - ImportDecl *Import = ImportDecl::Create(Context, + ImportDecl *Import = ImportDecl::Create(Context, Context.getTranslationUnitDecl(), - AtLoc.isValid()? AtLoc : ImportLoc, + AtLoc.isValid()? AtLoc : ImportLoc, Mod, IdentifierLocs); Context.getTranslationUnitDecl()->addDecl(Import); return Import; @@ -14938,7 +14940,7 @@ getLangOpts().CurrentModule.empty() || getLangOpts().CurrentModule != Mod->getTopLevelModuleName()); - // If this module import was due to an inclusion directive, create an + // If this module import was due to an inclusion directive, create an // implicit import declaration to capture it in the AST. if (ShouldAddImport) { TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); @@ -14948,7 +14950,7 @@ TU->addDecl(ImportD); Consumer.HandleImplicitImportDecl(ImportD); } - + getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc); VisibleModules.setVisible(Mod, DirectiveLoc); } Index: test/FixIt/typo.m =================================================================== --- test/FixIt/typo.m +++ test/FixIt/typo.m @@ -113,8 +113,6 @@ @end -double *isupper(int); - @interface Sub2 : Super - (int)method2; @end Index: test/Sema/enable_if.c =================================================================== --- test/Sema/enable_if.c +++ test/Sema/enable_if.c @@ -72,8 +72,8 @@ __attribute__((unavailable("'c' must have the value of an unsigned char or EOF"))); void test3(int c) { - isdigit(c); - isdigit(10); + isdigit(c); // expected-warning{{ignoring return value of function declared with pure attribute}} + isdigit(10); // expected-warning{{ignoring return value of function declared with pure attribute}} #ifndef CODEGEN isdigit(-10); // expected-error{{call to unavailable function 'isdigit': 'c' must have the value of an unsigned char or EOF}} #endif Index: test/Sema/libbuiltins-ctype-powerpc64.c =================================================================== --- test/Sema/libbuiltins-ctype-powerpc64.c +++ test/Sema/libbuiltins-ctype-powerpc64.c @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm < %s | FileCheck %s + +int isalnum(int); +int isalpha(int); +int isblank(int); +int iscntrl(int); +int isdigit(int); +int isgraph(int); +int islower(int); +int isprint(int); +int ispunct(int); +int isspace(int); +int isupper(int); +int isxdigit(int); +int tolower(int); +int toupper(int); + +void test(int x) { + // CHECK: call signext i32 @isalnum(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isalnum(x); + // CHECK: call signext i32 @isalpha(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isalpha(x); + // CHECK: call signext i32 @isblank(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isblank(x); + // CHECK: call signext i32 @iscntrl(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)iscntrl(x); + // CHECK: call signext i32 @isdigit(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isdigit(x); + // CHECK: call signext i32 @isgraph(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isgraph(x); + // CHECK: call signext i32 @islower(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)islower(x); + // CHECK: call signext i32 @isprint(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isprint(x); + // CHECK: call signext i32 @ispunct(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)ispunct(x); + // CHECK: call signext i32 @isspace(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isspace(x); + // CHECK: call signext i32 @isupper(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isupper(x); + // CHECK: call signext i32 @isxdigit(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isxdigit(x); + // CHECK: call signext i32 @tolower(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)tolower(x); + // CHECK: call signext i32 @toupper(i32 signext {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)toupper(x); +} + +// CHECK: declare signext i32 @isalnum(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @isalpha(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @isblank(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @iscntrl(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @isdigit(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @isgraph(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @islower(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @isprint(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @ispunct(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @isspace(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @isupper(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @isxdigit(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @tolower(i32 signext) [[NUW_RO:#[0-9]+]] +// CHECK: declare signext i32 @toupper(i32 signext) [[NUW_RO:#[0-9]+]] + +// CHECK: attributes [[NUW_RO]] = { nounwind readonly{{.*}} } +// CHECK: attributes [[NUW_RO_CALL]] = { nounwind readonly } Index: test/Sema/libbuiltins-ctype-x86_64.c =================================================================== --- test/Sema/libbuiltins-ctype-x86_64.c +++ test/Sema/libbuiltins-ctype-x86_64.c @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm < %s | FileCheck %s + +int isalnum(int); +int isalpha(int); +int isblank(int); +int iscntrl(int); +int isdigit(int); +int isgraph(int); +int islower(int); +int isprint(int); +int ispunct(int); +int isspace(int); +int isupper(int); +int isxdigit(int); +int tolower(int); +int toupper(int); + +void test(int x) { + // CHECK: call i32 @isalnum(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isalnum(x); + // CHECK: call i32 @isalpha(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isalpha(x); + // CHECK: call i32 @isblank(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isblank(x); + // CHECK: call i32 @iscntrl(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)iscntrl(x); + // CHECK: call i32 @isdigit(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isdigit(x); + // CHECK: call i32 @isgraph(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isgraph(x); + // CHECK: call i32 @islower(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)islower(x); + // CHECK: call i32 @isprint(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isprint(x); + // CHECK: call i32 @ispunct(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)ispunct(x); + // CHECK: call i32 @isspace(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isspace(x); + // CHECK: call i32 @isupper(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isupper(x); + // CHECK: call i32 @isxdigit(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)isxdigit(x); + // CHECK: call i32 @tolower(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)tolower(x); + // CHECK: call i32 @toupper(i32 {{%[0-9]+}}) [[NUW_RO_CALL:#[0-9]+]] + (void)toupper(x); +} + +// CHECK: declare i32 @isalnum(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @isalpha(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @isblank(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @iscntrl(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @isdigit(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @isgraph(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @islower(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @isprint(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @ispunct(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @isspace(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @isupper(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @isxdigit(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @tolower(i32) [[NUW_RO:#[0-9]+]] +// CHECK: declare i32 @toupper(i32) [[NUW_RO:#[0-9]+]] + +// CHECK: attributes [[NUW_RO]] = { nounwind readonly{{.*}} } +// CHECK: attributes [[NUW_RO_CALL]] = { nounwind readonly }