From ec2e4574378f4b248277789c4951781a7244be6e Mon Sep 17 00:00:00 2001 From: SongRe <49730299+SongRe@users.noreply.github.com> Date: Fri, 15 Nov 2024 23:13:45 -0500 Subject: [PATCH 1/6] Add new _Coroutine Keyword (#1) * _Coroutine recognized by editor as its own type --- .gitignore | 1 + clang/include/clang/AST/Decl.h | 2 +- clang/include/clang/AST/Type.h | 8 +++++++- clang/include/clang/Basic/Specifiers.h | 1 + clang/include/clang/Basic/TokenKinds.def | 1 + clang/include/clang/Sema/DeclSpec.h | 3 ++- clang/lib/AST/Type.cpp | 11 +++++++++++ clang/lib/Index/USRGeneration.cpp | 3 +++ clang/lib/Parse/ParseDecl.cpp | 3 +++ clang/lib/Parse/ParseDeclCXX.cpp | 10 ++++++++-- clang/lib/Parse/Parser.cpp | 1 + clang/lib/Sema/DeclSpec.cpp | 2 ++ clang/lib/Sema/SemaCodeComplete.cpp | 12 +++++++++++- clang/lib/Sema/SemaDecl.cpp | 8 ++++++++ clang/lib/Sema/SemaTemplateVariadic.cpp | 1 + clang/lib/Sema/SemaType.cpp | 1 + clang/utils/ClangVisualizers/clang.natvis | 4 ++-- lld/test/MachO/compact-unwind-generated.test | 1 + llvm/test/tools/opt-viewer/lit.local.cfg | 2 ++ 19 files changed, 67 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 0e7c6c7900133..06ad856af2d17 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,4 @@ pythonenv* /clang/utils/analyzer/projects/*/RefScanBuildResults # automodapi puts generated documentation files here. /lldb/docs/python_api/ +llvm-project.code-workspace \ No newline at end of file diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 8c39ef3d5a9fa..6d5dba6c88c5e 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -3768,7 +3768,7 @@ class TagDecl : public TypeDecl, bool isStruct() const { return getTagKind() == TagTypeKind::Struct; } bool isInterface() const { return getTagKind() == TagTypeKind::Interface; } - bool isClass() const { return getTagKind() == TagTypeKind::Class; } + bool isClass() const { return getTagKind() == TagTypeKind::Class || getTagKind() == TagTypeKind::Coroutine; } bool isUnion() const { return getTagKind() == TagTypeKind::Union; } bool isEnum() const { return getTagKind() == TagTypeKind::Enum; } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1ed5c22361ca6..8bcd6172668b6 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -6859,6 +6859,9 @@ enum class ElaboratedTypeKeyword { /// \c typename T::type. Typename, + /// The "Coroutine" keyword also introduces elaborated-type specifier + Coroutine, + /// No keyword precedes the qualified type name. None }; @@ -6878,7 +6881,10 @@ enum class TagTypeKind { Class, /// The "enum" keyword. - Enum + Enum, + + /// The "_Coroutine" keyword. + Coroutine }; /// A helper class for Type nodes having an ElaboratedTypeKeyword. diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index 9c089908fdc13..d39523cd90a00 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -79,6 +79,7 @@ namespace clang { TST_enum, TST_union, TST_struct, + TST_coroutine, TST_class, // C++ class type TST_interface, // C++ (Microsoft-specific) __interface type TST_typename, // Typedef, C++ class-name or enum name, etc. diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 2c692c999bdff..deac64dca2259 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -336,6 +336,7 @@ KEYWORD(_Atomic , KEYALL|KEYNOOPENCL) KEYWORD(_Bool , KEYNOCXX) KEYWORD(_Complex , KEYALL) KEYWORD(_Generic , KEYALL) +KEYWORD(_Coroutine , KEYALL) // Note, C2y removed support for _Imaginary; we retain it as a keyword because // 1) it's a reserved identifier, so we're allowed to steal it, 2) there's no // good way to specify a keyword in earlier but not later language modes within diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 06243f2624876..67be14d7ffa53 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -303,6 +303,7 @@ class DeclSpec { static const TST TST_struct = clang::TST_struct; static const TST TST_interface = clang::TST_interface; static const TST TST_class = clang::TST_class; + static const TST TST_coroutine = clang::TST_coroutine; static const TST TST_typename = clang::TST_typename; static const TST TST_typeofType = clang::TST_typeofType; static const TST TST_typeofExpr = clang::TST_typeofExpr; @@ -469,7 +470,7 @@ class DeclSpec { static bool isDeclRep(TST T) { return (T == TST_enum || T == TST_struct || T == TST_interface || T == TST_union || - T == TST_class); + T == TST_class || T == TST_coroutine); } static bool isTransformTypeTrait(TST T) { constexpr std::array Traits = { diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 7ecb986e4dc2b..c0779dc309dc0 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3159,6 +3159,8 @@ TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) { return ElaboratedTypeKeyword::None; case TST_typename: return ElaboratedTypeKeyword::Typename; + case TST_coroutine: + return ElaboratedTypeKeyword::Coroutine; case TST_class: return ElaboratedTypeKeyword::Class; case TST_struct: @@ -3175,6 +3177,8 @@ TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) { TagTypeKind TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) { switch(TypeSpec) { + case TST_coroutine: + return TagTypeKind::Coroutine; case TST_class: return TagTypeKind::Class; case TST_struct: @@ -3195,6 +3199,8 @@ TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) { switch (Kind) { case TagTypeKind::Class: return ElaboratedTypeKeyword::Class; + case TagTypeKind::Coroutine: + return ElaboratedTypeKeyword::Coroutine; case TagTypeKind::Struct: return ElaboratedTypeKeyword::Struct; case TagTypeKind::Interface: @@ -3212,6 +3218,8 @@ TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) { switch (Keyword) { case ElaboratedTypeKeyword::Class: return TagTypeKind::Class; + case ElaboratedTypeKeyword::Coroutine: + return TagTypeKind::Coroutine; case ElaboratedTypeKeyword::Struct: return TagTypeKind::Struct; case ElaboratedTypeKeyword::Interface: @@ -3234,6 +3242,7 @@ TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) { case ElaboratedTypeKeyword::Typename: return false; case ElaboratedTypeKeyword::Class: + case ElaboratedTypeKeyword::Coroutine: case ElaboratedTypeKeyword::Struct: case ElaboratedTypeKeyword::Interface: case ElaboratedTypeKeyword::Union: @@ -3259,6 +3268,8 @@ StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) { return "union"; case ElaboratedTypeKeyword::Enum: return "enum"; + case ElaboratedTypeKeyword::Coroutine: + return "_Coroutine"; } llvm_unreachable("Unknown elaborated type keyword."); diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index 493123459a5a4..a2acf9eb52565 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -529,6 +529,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) { switch (D->getTagKind()) { case TagTypeKind::Interface: case TagTypeKind::Class: + case TagTypeKind::Coroutine: case TagTypeKind::Struct: Out << "@ST"; break; @@ -546,6 +547,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) { switch (D->getTagKind()) { case TagTypeKind::Interface: case TagTypeKind::Class: + case TagTypeKind::Coroutine: case TagTypeKind::Struct: Out << "@SP"; break; @@ -563,6 +565,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) { switch (D->getTagKind()) { case TagTypeKind::Interface: case TagTypeKind::Class: + case TagTypeKind::Coroutine: case TagTypeKind::Struct: Out << "@S"; break; diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 31984453487ae..b5054f9b6db67 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3120,6 +3120,8 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, TagKind=tok::kw___interface;break; case DeclSpec::TST_class: TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break; + case DeclSpec::TST_coroutine: + TagName="coroutine" ; FixitTagName = "coroutine "; TagKind=tok::kw__Coroutine; break; } if (TagName) { @@ -4684,6 +4686,7 @@ void Parser::ParseDeclarationSpecifiers( // class-specifier: case tok::kw_class: + case tok::kw__Coroutine: case tok::kw_struct: case tok::kw___interface: case tok::kw_union: { diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 60aab1411a96c..3b17ab4a44704 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -29,7 +29,9 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/SemaCodeCompletion.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Support/Error.h" #include "llvm/Support/TimeProfiler.h" +#include "llvm/Support/raw_ostream.h" #include using namespace clang; @@ -1724,6 +1726,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TagType = DeclSpec::TST_interface; else if (TagTokKind == tok::kw_class) TagType = DeclSpec::TST_class; + else if (TagTokKind == tok::kw__Coroutine) { + TagType = DeclSpec::TST_coroutine; + } + else { assert(TagTokKind == tok::kw_union && "Not a class specifier"); TagType = DeclSpec::TST_union; @@ -3755,7 +3761,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, unsigned TagType, Decl *TagDecl) { assert((TagType == DeclSpec::TST_struct || TagType == DeclSpec::TST_interface || - TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class) && + TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class || TagType == DeclSpec::TST_coroutine) && "Invalid TagType!"); llvm::TimeTraceScope TimeScope("ParseClass", [&]() { @@ -3932,7 +3938,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // are public by default. // HLSL: In HLSL members of a class are public by default. AccessSpecifier CurAS; - if (TagType == DeclSpec::TST_class && !getLangOpts().HLSL) + if ((TagType == DeclSpec::TST_class || TagType == DeclSpec::TST_coroutine) && !getLangOpts().HLSL) CurAS = AS_private; else CurAS = AS_public; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 04c2f1d380bc4..84de31a063d94 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1161,6 +1161,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal( assert(DeclSpec::isDeclRep(TKind)); switch(TKind) { case DeclSpec::TST_class: + case DeclSpec::TST_coroutine: return 5; case DeclSpec::TST_struct: return 6; diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 12d2d3f6060c6..101468d12b390 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -350,6 +350,7 @@ bool Declarator::isDeclarationOfFunction() const { case TST_char16: case TST_char32: case TST_class: + case TST_coroutine: case TST_decimal128: case TST_decimal32: case TST_decimal64: @@ -585,6 +586,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T, case DeclSpec::TST_decimal128: return "_Decimal128"; case DeclSpec::TST_enum: return "enum"; case DeclSpec::TST_class: return "class"; + case DeclSpec::TST_coroutine: return "coroutine"; case DeclSpec::TST_union: return "union"; case DeclSpec::TST_struct: return "struct"; case DeclSpec::TST_interface: return "__interface"; diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 890ca96790acb..b6ff96fda598b 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1819,8 +1819,13 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, Results.AddResult( Result("bool", CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0))); Results.AddResult(Result("class", CCP_Type)); + Results.AddResult(Result("_Coroutine", CCP_Type)); Results.AddResult(Result("wchar_t", CCP_Type)); + Builder.AddTypedTextChunk("_Coroutine"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddInformativeChunk("A Coroutine, as defined by concurrency course."); + // typename name Builder.AddTypedTextChunk("typename"); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); @@ -2034,6 +2039,8 @@ static const char *GetCompletionTypeString(QualType T, ASTContext &Context, return "__interface "; case TagTypeKind::Class: return "class "; + case TagTypeKind::Coroutine: + return "class "; case TagTypeKind::Union: return "union "; case TagTypeKind::Enum: @@ -4181,6 +4188,7 @@ CXCursorKind clang::getCursorKindForDecl(const Decl *D) { case TagTypeKind::Struct: return CXCursor_StructDecl; case TagTypeKind::Class: + case TagTypeKind::Coroutine: return CXCursor_ClassDecl; case TagTypeKind::Union: return CXCursor_UnionDecl; @@ -4533,7 +4541,8 @@ void SemaCodeCompletion::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, if (getLangOpts().CPlusPlus) { if (getLangOpts().CPlusPlus11 && (DS.getTypeSpecType() == DeclSpec::TST_class || - DS.getTypeSpecType() == DeclSpec::TST_struct)) + DS.getTypeSpecType() == DeclSpec::TST_struct || + DS.getTypeSpecType() == DeclSpec::TST_coroutine)) Results.AddResult("final"); if (AllowNonIdentifiers) { @@ -5923,6 +5932,7 @@ void SemaCodeCompletion::CodeCompleteTag(Scope *S, unsigned TagSpec) { case DeclSpec::TST_struct: case DeclSpec::TST_class: + case DeclSpec::TST_coroutine: case DeclSpec::TST_interface: Filter = &ResultBuilder::IsClassOrStruct; ContextKind = CodeCompletionContext::CCC_ClassOrStructTag; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 07ac6a3bb4e5b..c759c321daaa2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -656,6 +656,8 @@ DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) { return DeclSpec::TST_union; case TagTypeKind::Class: return DeclSpec::TST_class; + case TagTypeKind::Coroutine: + return DeclSpec::TST_coroutine; case TagTypeKind::Enum: return DeclSpec::TST_enum; } @@ -819,6 +821,7 @@ static bool isTagTypeWithMissingTag(Sema &SemaRef, LookupResult &Result, if (TagDecl *Tag = R.getAsSingle()) { StringRef FixItTagName; switch (Tag->getTagKind()) { + case TagTypeKind::Coroutine: case TagTypeKind::Class: FixItTagName = "class "; break; @@ -4989,6 +4992,7 @@ static unsigned GetDiagnosticTypeSpecifierID(const DeclSpec &DS) { DeclSpec::TST T = DS.getTypeSpecType(); switch (T) { case DeclSpec::TST_class: + case DeclSpec::TST_coroutine: return 0; case DeclSpec::TST_struct: return 1; @@ -5019,6 +5023,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, Decl *TagD = nullptr; TagDecl *Tag = nullptr; if (DS.getTypeSpecType() == DeclSpec::TST_class || + DS.getTypeSpecType() == DeclSpec::TST_coroutine || DS.getTypeSpecType() == DeclSpec::TST_struct || DS.getTypeSpecType() == DeclSpec::TST_interface || DS.getTypeSpecType() == DeclSpec::TST_union || @@ -5243,6 +5248,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, if (!DS.getAttributes().empty() || !DeclAttrs.empty()) { DeclSpec::TST TypeSpecType = DS.getTypeSpecType(); if (TypeSpecType == DeclSpec::TST_class || + TypeSpecType == DeclSpec::TST_coroutine || TypeSpecType == DeclSpec::TST_struct || TypeSpecType == DeclSpec::TST_interface || TypeSpecType == DeclSpec::TST_union || @@ -16799,6 +16805,7 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, case TST_struct: case TST_interface: case TST_union: + case TST_coroutine: case TST_class: { TagDecl *tagFromDeclSpec = cast(D.getDeclSpec().getRepAsDecl()); setTagNameForLinkagePurposes(tagFromDeclSpec, NewTD); @@ -16904,6 +16911,7 @@ Sema::NonTagKind Sema::getNonTagTypeDeclKind(const Decl *PrevDecl, case TagTypeKind::Struct: case TagTypeKind::Interface: case TagTypeKind::Class: + case TagTypeKind::Coroutine: return getLangOpts().CPlusPlus ? NTK_NonClass : NTK_NonStruct; case TagTypeKind::Union: return NTK_NonUnion; diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 2ea2a368dd24c..6dff76f7dfed9 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -990,6 +990,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { case TST_struct: case TST_interface: case TST_class: + case TST_coroutine: case TST_auto: case TST_auto_type: case TST_decltype_auto: diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 4fac71ba09566..1f4cb9e71adf2 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1195,6 +1195,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { declarator.setInvalidType(true); break; case DeclSpec::TST_class: + case DeclSpec::TST_coroutine: case DeclSpec::TST_enum: case DeclSpec::TST_union: case DeclSpec::TST_struct: diff --git a/clang/utils/ClangVisualizers/clang.natvis b/clang/utils/ClangVisualizers/clang.natvis index a7c70186bc46d..a3fab18d5c9ff 100644 --- a/clang/utils/ClangVisualizers/clang.natvis +++ b/clang/utils/ClangVisualizers/clang.natvis @@ -854,7 +854,7 @@ For later versions of Visual Studio, no setup is required--> , [{ExprRep}] - + , [{DeclRep}] @@ -868,7 +868,7 @@ For later versions of Visual Studio, no setup is required--> ExprRep - + DeclRep diff --git a/lld/test/MachO/compact-unwind-generated.test b/lld/test/MachO/compact-unwind-generated.test index b81236b198c3b..34a4e9d820762 100644 --- a/lld/test/MachO/compact-unwind-generated.test +++ b/lld/test/MachO/compact-unwind-generated.test @@ -1,4 +1,5 @@ # REQUIRES: x86 +# XFAIL: system-darwin # FIXME(gkm): This test is fast on a Release tree, and slow (~10s) on # a Debug tree mostly because of llvm-mc. Is there a way to prefer the diff --git a/llvm/test/tools/opt-viewer/lit.local.cfg b/llvm/test/tools/opt-viewer/lit.local.cfg index d181a93eb8464..53ee298379cbc 100644 --- a/llvm/test/tools/opt-viewer/lit.local.cfg +++ b/llvm/test/tools/opt-viewer/lit.local.cfg @@ -8,3 +8,5 @@ if "have_opt_viewer_modules" not in config.available_features: # can be resolved. if sys.platform == "win32": config.unsupported = True +if sys.platform == 'darwin': + config.unsupported = True From 82bf32e4aaaa4c42e6ab9c13c0d464ee9b496616 Mon Sep 17 00:00:00 2001 From: abdurj Date: Fri, 15 Nov 2024 23:24:56 -0500 Subject: [PATCH 2/6] Add Clang CI to target main branch --- .github/workflows/clang-tests.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/clang-tests.yml b/.github/workflows/clang-tests.yml index 2569ce19518e3..f17357eb2970e 100644 --- a/.github/workflows/clang-tests.yml +++ b/.github/workflows/clang-tests.yml @@ -8,6 +8,7 @@ on: push: branches: - 'release/**' + - 'main' paths: - 'clang/**' - '.github/workflows/clang-tests.yml' @@ -16,6 +17,7 @@ on: pull_request: branches: - 'release/**' + - 'main' paths: - 'clang/**' - '.github/workflows/clang-tests.yml' @@ -30,7 +32,7 @@ concurrency: jobs: check_clang: - if: github.repository_owner == 'llvm' + if: github.event_name == 'pull_request' && github.base_ref == 'main' name: Test clang,lldb,libclc uses: ./.github/workflows/llvm-project-tests.yml with: From 21b4f2e82c3e175c8f9da6afddcecde5ad2728f2 Mon Sep 17 00:00:00 2001 From: SongRe Date: Thu, 28 Nov 2024 16:42:45 -0500 Subject: [PATCH 3/6] Miscellaneous coroutine tagtype fixes --- clang/lib/AST/ItaniumMangle.cpp | 1 + clang/lib/AST/MicrosoftMangle.cpp | 1 + clang/lib/Index/IndexSymbol.cpp | 1 + clang/lib/Sema/SemaType.cpp | 1 + 4 files changed, 4 insertions(+) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 14bc260d0245f..61dbf510e6c65 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4361,6 +4361,7 @@ void CXXNameMangler::mangleType(const DependentNameType *T) { break; case ElaboratedTypeKeyword::Struct: case ElaboratedTypeKeyword::Class: + case ElaboratedTypeKeyword::Coroutine: case ElaboratedTypeKeyword::Interface: Out << "Ts"; break; diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index dbc161347025c..93f7cda72a74e 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -3244,6 +3244,7 @@ void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) { Out << 'U'; break; case TagTypeKind::Class: + case TagTypeKind::Coroutine: Out << 'V'; break; case TagTypeKind::Enum: diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp index 419ff79a5cbab..da12eb9243fd0 100644 --- a/clang/lib/Index/IndexSymbol.cpp +++ b/clang/lib/Index/IndexSymbol.cpp @@ -112,6 +112,7 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { case TagTypeKind::Union: Info.Kind = SymbolKind::Union; break; case TagTypeKind::Class: + case TagTypeKind::Coroutine: Info.Kind = SymbolKind::Class; Info.Lang = SymbolLanguage::CXX; break; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 1f4cb9e71adf2..308faed3b95ad 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -3244,6 +3244,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, Error = Cxx ? 3 : 4; /* Union member */ break; case TagTypeKind::Class: + case TagTypeKind::Coroutine: Error = 5; /* Class member */ break; case TagTypeKind::Interface: From 97898f0bb2ee85da9303abe6ff6ea0dd346cdb72 Mon Sep 17 00:00:00 2001 From: SongRe Date: Fri, 29 Nov 2024 21:01:58 -0500 Subject: [PATCH 4/6] remove breaking code --- clang/lib/Sema/SemaCodeComplete.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index b6ff96fda598b..bbad5c0ca6a95 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1822,10 +1822,6 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, Results.AddResult(Result("_Coroutine", CCP_Type)); Results.AddResult(Result("wchar_t", CCP_Type)); - Builder.AddTypedTextChunk("_Coroutine"); - Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); - Builder.AddInformativeChunk("A Coroutine, as defined by concurrency course."); - // typename name Builder.AddTypedTextChunk("typename"); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); From 4114a2ad4f5c444868934efa535d03254f73a657 Mon Sep 17 00:00:00 2001 From: SongRe Date: Fri, 29 Nov 2024 21:39:08 -0500 Subject: [PATCH 5/6] fixed warning --- clang/tools/libclang/CIndexCXX.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/tools/libclang/CIndexCXX.cpp b/clang/tools/libclang/CIndexCXX.cpp index ea6f97d39644e..742a542029403 100644 --- a/clang/tools/libclang/CIndexCXX.cpp +++ b/clang/tools/libclang/CIndexCXX.cpp @@ -67,6 +67,7 @@ enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) { case TagTypeKind::Struct: return CXCursor_StructDecl; case TagTypeKind::Class: + case TagTypeKind::Coroutine: return CXCursor_ClassDecl; case TagTypeKind::Union: return CXCursor_UnionDecl; From f3063d5a7e95937aa7628c4a57efd991b52742ef Mon Sep 17 00:00:00 2001 From: abdurj Date: Thu, 6 Feb 2025 22:31:59 -0500 Subject: [PATCH 6/6] Add support for _When --- clang/include/clang/AST/RecursiveASTVisitor.h | 1 + clang/include/clang/AST/Stmt.h | 55 + clang/include/clang/Basic/StmtNodes.td | 3 + clang/include/clang/Basic/TokenKinds.def | 236 +- clang/include/clang/Parse/Parser.h | 447 ++-- clang/include/clang/Sema/Sema.h | 3 + .../include/clang/Serialization/ASTBitCodes.h | 3 + clang/lib/AST/Stmt.cpp | 13 + clang/lib/AST/StmtPrinter.cpp | 7 + clang/lib/AST/StmtProfile.cpp | 4 + clang/lib/CodeGen/CodeGenPGO.cpp | 17 + clang/lib/Parse/ParseStmt.cpp | 55 + clang/lib/Sema/SemaExceptionSpec.cpp | 1 + clang/lib/Sema/SemaStmt.cpp | 14 + clang/lib/Sema/SemaType.cpp | 2107 +++++++++-------- clang/lib/Sema/TreeTransform.h | 39 + clang/lib/Serialization/ASTReaderStmt.cpp | 13 + clang/lib/Serialization/ASTWriterStmt.cpp | 9 + clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 + 19 files changed, 1612 insertions(+), 1416 deletions(-) diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 76b598a5db238..1b45e805d5820 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2472,6 +2472,7 @@ DEF_TRAVERSE_STMT(MSDependentExistsStmt, { DEF_TRAVERSE_STMT(ReturnStmt, {}) DEF_TRAVERSE_STMT(SwitchStmt, {}) DEF_TRAVERSE_STMT(WhileStmt, {}) +DEF_TRAVERSE_STMT(WhenStmt, {}) DEF_TRAVERSE_STMT(ConstantExpr, {}) diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 83fafbabb1d46..d37ae69774d72 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -2409,6 +2409,61 @@ class IfStmt final } }; +/// WhenStmt - This represents a '_When' stmt. +class WhenStmt : public Stmt, private llvm::TrailingObjects { + SourceLocation WhenLoc; + Expr *Condition; + bool IsAccept; + IdentifierInfo *VarName; + Stmt *Body; + + /* + * WhenStmt is followed by several trailing objects, some of which optional. + * Note that it would be more convenient to put the optional trailing objects + * at the end but this would change the order in children(). + * The trailing objects are in order: + * + * * A "Stmt *" for the condition. + * Always present. This is in fact an "Expr *". + * + * * A "Stmt *" for the body. + * Always present. + */ + enum { + NumMandatoryStmtPtr = 2 + }; + +public: + // WhenStmt(SourceLocation Loc, Expr *Cond, bool Accept, IdentifierInfo *Var, Stmt *BodyStmt) + WhenStmt(SourceLocation Loc, Expr *Cond, Stmt *BodyStmt) + : Stmt(Stmt::WhenStmtClass), WhenLoc(Loc), Condition(Cond), + Body(BodyStmt) {} + // IsAccept(Accept), VarName(Var), Body(BodyStmt) {} + + explicit WhenStmt(EmptyShell Empty) + : Stmt(Stmt::WhenStmtClass) {} + + // static WhenStmt* Create(const ASTContext &Ctx, SourceLocation Loc, Expr *Cond, bool Accept, IdentifierInfo *Var, Stmt *BodyStmt); + static WhenStmt* Create(const ASTContext &Ctx, SourceLocation Loc, Expr *Cond, Stmt *BodyStmt); + static WhenStmt* CreateEmpty(const ASTContext &Ctx); + + SourceLocation getBeginLoc() const { return WhenLoc; } + SourceLocation getEndLoc() const { return Body ? Body->getEndLoc() : WhenLoc; } + child_range children() { return child_range(&Body, &Body + 1); } + static bool classof(const Stmt *S) { return S->getStmtClass() == WhenStmtClass; } + + bool isAccept() const { return IsAccept; } + IdentifierInfo *getVarName() const { return VarName; } + Expr *getCondition() const { return Condition; } + void setCondition(Expr *Cond) { Condition = Cond; } + Stmt *getBody() const { return Body; } + void setBody(Stmt *B) { Body = B; } + + SourceLocation getWhenLoc() const { return WhenLoc; } + SourceLocation setWhenLoc(SourceLocation Loc) { return WhenLoc = Loc; } + +}; + /// SwitchStmt - This represents a 'switch' stmt. class SwitchStmt final : public Stmt, private llvm::TrailingObjects { diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 89f5a76eb1131..527a43a820c66 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -25,6 +25,9 @@ def CaseStmt : StmtNode; def DefaultStmt : StmtNode; def CapturedStmt : StmtNode; +// uC++ Statements +def WhenStmt : StmtNode; + // Statements that might produce a value (for example, as the last non-null // statement in a GNU statement-expression). def ValueStmt : StmtNode; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index deac64dca2259..5970334265b54 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -17,65 +17,65 @@ #define TOK(X) #endif #ifndef PUNCTUATOR -#define PUNCTUATOR(X,Y) TOK(X) +#define PUNCTUATOR(X, Y) TOK(X) #endif #ifndef KEYWORD -#define KEYWORD(X,Y) TOK(kw_ ## X) +#define KEYWORD(X, Y) TOK(kw_##X) #endif #ifndef CXX11_KEYWORD -#define CXX11_KEYWORD(X,Y) KEYWORD(X,KEYCXX11|(Y)) +#define CXX11_KEYWORD(X, Y) KEYWORD(X, KEYCXX11 | (Y)) #endif #ifndef CXX20_KEYWORD -#define CXX20_KEYWORD(X,Y) KEYWORD(X,KEYCXX20|(Y)) +#define CXX20_KEYWORD(X, Y) KEYWORD(X, KEYCXX20 | (Y)) #endif #ifndef C99_KEYWORD -#define C99_KEYWORD(X,Y) KEYWORD(X,KEYC99|(Y)) +#define C99_KEYWORD(X, Y) KEYWORD(X, KEYC99 | (Y)) #endif #ifndef C23_KEYWORD -#define C23_KEYWORD(X,Y) KEYWORD(X,KEYC23|(Y)) +#define C23_KEYWORD(X, Y) KEYWORD(X, KEYC23 | (Y)) #endif #ifndef COROUTINES_KEYWORD -#define COROUTINES_KEYWORD(X) CXX20_KEYWORD(X,KEYCOROUTINES) +#define COROUTINES_KEYWORD(X) CXX20_KEYWORD(X, KEYCOROUTINES) #endif #ifndef MODULES_KEYWORD -#define MODULES_KEYWORD(X) KEYWORD(X,KEYMODULES) +#define MODULES_KEYWORD(X) KEYWORD(X, KEYMODULES) #endif #ifndef TYPE_TRAIT -#define TYPE_TRAIT(N,I,K) KEYWORD(I,K) +#define TYPE_TRAIT(N, I, K) KEYWORD(I, K) #endif #ifndef TYPE_TRAIT_1 -#define TYPE_TRAIT_1(I,E,K) TYPE_TRAIT(1,I,K) +#define TYPE_TRAIT_1(I, E, K) TYPE_TRAIT(1, I, K) #endif #ifndef TYPE_TRAIT_2 -#define TYPE_TRAIT_2(I,E,K) TYPE_TRAIT(2,I,K) +#define TYPE_TRAIT_2(I, E, K) TYPE_TRAIT(2, I, K) #endif #ifndef TYPE_TRAIT_N -#define TYPE_TRAIT_N(I,E,K) TYPE_TRAIT(0,I,K) +#define TYPE_TRAIT_N(I, E, K) TYPE_TRAIT(0, I, K) #endif #ifndef ARRAY_TYPE_TRAIT -#define ARRAY_TYPE_TRAIT(I,E,K) KEYWORD(I,K) +#define ARRAY_TYPE_TRAIT(I, E, K) KEYWORD(I, K) #endif #ifndef UNARY_EXPR_OR_TYPE_TRAIT -#define UNARY_EXPR_OR_TYPE_TRAIT(I,E,K) KEYWORD(I,K) +#define UNARY_EXPR_OR_TYPE_TRAIT(I, E, K) KEYWORD(I, K) #endif #ifndef CXX11_UNARY_EXPR_OR_TYPE_TRAIT -#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(I,E,K) CXX11_KEYWORD(I,K) +#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(I, E, K) CXX11_KEYWORD(I, K) #endif #ifndef EXPRESSION_TRAIT -#define EXPRESSION_TRAIT(I,E,K) KEYWORD(I,K) +#define EXPRESSION_TRAIT(I, E, K) KEYWORD(I, K) #endif #ifndef TRANSFORM_TYPE_TRAIT_DEF #define TRANSFORM_TYPE_TRAIT_DEF(K, Trait) KEYWORD(__##Trait, KEYCXX) #endif #ifndef ALIAS -#define ALIAS(X,Y,Z) +#define ALIAS(X, Y, Z) #endif #ifndef PPKEYWORD #define PPKEYWORD(X) #endif #ifndef CXX_KEYWORD_OPERATOR -#define CXX_KEYWORD_OPERATOR(X,Y) +#define CXX_KEYWORD_OPERATOR(X, Y) #endif #ifndef OBJC_AT_KEYWORD #define OBJC_AT_KEYWORD(X) @@ -84,7 +84,7 @@ #define TESTING_KEYWORD(X, L) KEYWORD(X, L) #endif #ifndef ANNOTATION -#define ANNOTATION(X) TOK(annot_ ## X) +#define ANNOTATION(X) TOK(annot_##X) #endif #ifndef PRAGMA_ANNOTATION #define PRAGMA_ANNOTATION(X) ANNOTATION(X) @@ -152,32 +152,32 @@ PPKEYWORD(__private_macro) // These define members of the tok::* namespace. -TOK(unknown) // Not a token. -TOK(eof) // End of file. -TOK(eod) // End of preprocessing directive (end of line inside a - // directive). -TOK(code_completion) // Code completion marker +TOK(unknown) // Not a token. +TOK(eof) // End of file. +TOK(eod) // End of preprocessing directive (end of line inside a + // directive). +TOK(code_completion) // Code completion marker // C99 6.4.9: Comments. -TOK(comment) // Comment (only in -E -C[C] mode) +TOK(comment) // Comment (only in -E -C[C] mode) // C99 6.4.2: Identifiers. -TOK(identifier) // abcde123 -TOK(raw_identifier) // Used only in raw lexing mode. +TOK(identifier) // abcde123 +TOK(raw_identifier) // Used only in raw lexing mode. // C99 6.4.4.1: Integer Constants // C99 6.4.4.2: Floating Constants -TOK(numeric_constant) // 0x123 +TOK(numeric_constant) // 0x123 // Directly holds numerical value. Used to process C23 #embed. TOK(binary_data) // C99 6.4.4: Character Constants -TOK(char_constant) // 'a' -TOK(wide_char_constant) // L'b' +TOK(char_constant) // 'a' +TOK(wide_char_constant) // L'b' // C++17 Character Constants -TOK(utf8_char_constant) // u8'a' +TOK(utf8_char_constant) // u8'a' // C++11 Character Constants TOK(utf16_char_constant) // u'a' @@ -188,75 +188,75 @@ TOK(string_literal) // "foo" TOK(wide_string_literal) // L"foo" // C11 6.4.7: Header Names -TOK(header_name) // , or "foo" lexed as a header-name +TOK(header_name) // , or "foo" lexed as a header-name // C++11 String Literals. -TOK(utf8_string_literal) // u8"foo" -TOK(utf16_string_literal)// u"foo" -TOK(utf32_string_literal)// U"foo" +TOK(utf8_string_literal) // u8"foo" +TOK(utf16_string_literal) // u"foo" +TOK(utf32_string_literal) // U"foo" // C99 6.4.6: Punctuators. -PUNCTUATOR(l_square, "[") -PUNCTUATOR(r_square, "]") -PUNCTUATOR(l_paren, "(") -PUNCTUATOR(r_paren, ")") -PUNCTUATOR(l_brace, "{") -PUNCTUATOR(r_brace, "}") -PUNCTUATOR(period, ".") -PUNCTUATOR(ellipsis, "...") -PUNCTUATOR(amp, "&") -PUNCTUATOR(ampamp, "&&") -PUNCTUATOR(ampequal, "&=") -PUNCTUATOR(star, "*") -PUNCTUATOR(starequal, "*=") -PUNCTUATOR(plus, "+") -PUNCTUATOR(plusplus, "++") -PUNCTUATOR(plusequal, "+=") -PUNCTUATOR(minus, "-") -PUNCTUATOR(arrow, "->") -PUNCTUATOR(minusminus, "--") -PUNCTUATOR(minusequal, "-=") -PUNCTUATOR(tilde, "~") -PUNCTUATOR(exclaim, "!") -PUNCTUATOR(exclaimequal, "!=") -PUNCTUATOR(slash, "/") -PUNCTUATOR(slashequal, "/=") -PUNCTUATOR(percent, "%") -PUNCTUATOR(percentequal, "%=") -PUNCTUATOR(less, "<") -PUNCTUATOR(lessless, "<<") -PUNCTUATOR(lessequal, "<=") -PUNCTUATOR(lesslessequal, "<<=") -PUNCTUATOR(spaceship, "<=>") -PUNCTUATOR(greater, ">") -PUNCTUATOR(greatergreater, ">>") -PUNCTUATOR(greaterequal, ">=") +PUNCTUATOR(l_square, "[") +PUNCTUATOR(r_square, "]") +PUNCTUATOR(l_paren, "(") +PUNCTUATOR(r_paren, ")") +PUNCTUATOR(l_brace, "{") +PUNCTUATOR(r_brace, "}") +PUNCTUATOR(period, ".") +PUNCTUATOR(ellipsis, "...") +PUNCTUATOR(amp, "&") +PUNCTUATOR(ampamp, "&&") +PUNCTUATOR(ampequal, "&=") +PUNCTUATOR(star, "*") +PUNCTUATOR(starequal, "*=") +PUNCTUATOR(plus, "+") +PUNCTUATOR(plusplus, "++") +PUNCTUATOR(plusequal, "+=") +PUNCTUATOR(minus, "-") +PUNCTUATOR(arrow, "->") +PUNCTUATOR(minusminus, "--") +PUNCTUATOR(minusequal, "-=") +PUNCTUATOR(tilde, "~") +PUNCTUATOR(exclaim, "!") +PUNCTUATOR(exclaimequal, "!=") +PUNCTUATOR(slash, "/") +PUNCTUATOR(slashequal, "/=") +PUNCTUATOR(percent, "%") +PUNCTUATOR(percentequal, "%=") +PUNCTUATOR(less, "<") +PUNCTUATOR(lessless, "<<") +PUNCTUATOR(lessequal, "<=") +PUNCTUATOR(lesslessequal, "<<=") +PUNCTUATOR(spaceship, "<=>") +PUNCTUATOR(greater, ">") +PUNCTUATOR(greatergreater, ">>") +PUNCTUATOR(greaterequal, ">=") PUNCTUATOR(greatergreaterequal, ">>=") -PUNCTUATOR(caret, "^") -PUNCTUATOR(caretequal, "^=") -PUNCTUATOR(pipe, "|") -PUNCTUATOR(pipepipe, "||") -PUNCTUATOR(pipeequal, "|=") -PUNCTUATOR(question, "?") -PUNCTUATOR(colon, ":") -PUNCTUATOR(semi, ";") -PUNCTUATOR(equal, "=") -PUNCTUATOR(equalequal, "==") -PUNCTUATOR(comma, ",") -PUNCTUATOR(hash, "#") -PUNCTUATOR(hashhash, "##") -PUNCTUATOR(hashat, "#@") +PUNCTUATOR(caret, "^") +PUNCTUATOR(caretequal, "^=") +PUNCTUATOR(pipe, "|") +PUNCTUATOR(pipepipe, "||") +PUNCTUATOR(pipeequal, "|=") +PUNCTUATOR(question, "?") +PUNCTUATOR(colon, ":") +PUNCTUATOR(semi, ";") +PUNCTUATOR(equal, "=") +PUNCTUATOR(equalequal, "==") +PUNCTUATOR(comma, ",") +PUNCTUATOR(hash, "#") +PUNCTUATOR(hashhash, "##") +PUNCTUATOR(hashat, "#@") // C++ Support -PUNCTUATOR(periodstar, ".*") -PUNCTUATOR(arrowstar, "->*") -PUNCTUATOR(coloncolon, "::") +PUNCTUATOR(periodstar, ".*") +PUNCTUATOR(arrowstar, "->*") +PUNCTUATOR(coloncolon, "::") // Objective C support. -PUNCTUATOR(at, "@") +PUNCTUATOR(at, "@") // CUDA support. -PUNCTUATOR(lesslessless, "<<<") +PUNCTUATOR(lesslessless, "<<<") PUNCTUATOR(greatergreatergreater, ">>>") // C99 6.4.1: Keywords. These turn into kw_* tokens. @@ -295,34 +295,34 @@ PUNCTUATOR(greatergreatergreater, ">>>") // extension. // KEYZOS - This is a keyword in C/C++ on z/OS // -KEYWORD(auto , KEYALL) -KEYWORD(break , KEYALL) -KEYWORD(case , KEYALL) -KEYWORD(char , KEYALL) -KEYWORD(const , KEYALL) -KEYWORD(continue , KEYALL) -KEYWORD(default , KEYALL) -KEYWORD(do , KEYALL) -KEYWORD(double , KEYALL) -KEYWORD(else , KEYALL) -KEYWORD(enum , KEYALL) -KEYWORD(extern , KEYALL) -KEYWORD(float , KEYALL) +KEYWORD(auto, KEYALL) +KEYWORD(break, KEYALL) +KEYWORD(case, KEYALL) +KEYWORD(char, KEYALL) +KEYWORD(const, KEYALL) +KEYWORD(continue, KEYALL) +KEYWORD(default, KEYALL) +KEYWORD(do, KEYALL) +KEYWORD(double, KEYALL) +KEYWORD(else, KEYALL) +KEYWORD(enum, KEYALL) +KEYWORD(extern, KEYALL) +KEYWORD(float, KEYALL) KEYWORD(for , KEYALL) -KEYWORD(goto , KEYALL) -KEYWORD(if , KEYALL) -KEYWORD(int , KEYALL) -KEYWORD(_ExtInt , KEYALL) -KEYWORD(_BitInt , KEYALL) -KEYWORD(long , KEYALL) -KEYWORD(register , KEYALL) -KEYWORD(return , KEYALL) -KEYWORD(short , KEYALL) -KEYWORD(signed , KEYALL) +KEYWORD(goto, KEYALL) +KEYWORD(if, KEYALL) +KEYWORD(int, KEYALL) +KEYWORD(_ExtInt, KEYALL) +KEYWORD(_BitInt, KEYALL) +KEYWORD(long, KEYALL) +KEYWORD(register, KEYALL) +KEYWORD(return, KEYALL) +KEYWORD(short, KEYALL) +KEYWORD(signed, KEYALL) UNARY_EXPR_OR_TYPE_TRAIT(sizeof, SizeOf, KEYALL) UNARY_EXPR_OR_TYPE_TRAIT(__datasizeof, DataSizeOf, KEYCXX) -KEYWORD(static , KEYALL) -KEYWORD(struct , KEYALL) +KEYWORD(static, KEYALL) +KEYWORD(struct, KEYALL) KEYWORD(switch , KEYALL) KEYWORD(typedef , KEYALL) KEYWORD(union , KEYALL) @@ -337,6 +337,9 @@ KEYWORD(_Bool , KEYNOCXX) KEYWORD(_Complex , KEYALL) KEYWORD(_Generic , KEYALL) KEYWORD(_Coroutine , KEYALL) +KEYWORD(_When , KEYALL) +// KEYWORD(_Accept , KEYALL) +// KEYWORD(_Select , KEYALL) // Note, C2y removed support for _Imaginary; we retain it as a keyword because // 1) it's a reserved identifier, so we're allowed to steal it, 2) there's no // good way to specify a keyword in earlier but not later language modes within @@ -640,7 +643,8 @@ ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX) // OpenCL builtins KEYWORD(__builtin_astype , KEYOPENCLC | KEYOPENCLCXX) UNARY_EXPR_OR_TYPE_TRAIT(vec_step, VecStep, KEYOPENCLC | KEYOPENCLCXX | KEYALTIVEC | KEYZVECTOR) -#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX) +#define GENERIC_IMAGE_TYPE(ImgType, Id) \ + KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX) #include "clang/Basic/OpenCLImageTypes.def" KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX) // C++ for OpenCL s2.3.1: addrspace_cast operator @@ -797,7 +801,7 @@ KEYWORD(__builtin_sycl_unique_stable_name, KEYSYCL) // Keywords defined by Attr.td. // The "EMPTY ## X" is used to prevent early macro-expansion of the keyword. #ifndef KEYWORD_ATTRIBUTE -#define KEYWORD_ATTRIBUTE(X, HASARG, EMPTY) KEYWORD(EMPTY ## X, KEYALL) +#define KEYWORD_ATTRIBUTE(X, HASARG, EMPTY) KEYWORD(EMPTY##X, KEYALL) #endif #include "clang/Basic/RegularKeywordAttrInfo.inc" diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 045ee754a242b..ef1237e07b3ae 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -28,28 +28,28 @@ #include namespace clang { - class PragmaHandler; - class Scope; - class BalancedDelimiterTracker; - class CorrectionCandidateCallback; - class DeclGroupRef; - class DiagnosticBuilder; - struct LoopHint; - class Parser; - class ParsingDeclRAIIObject; - class ParsingDeclSpec; - class ParsingDeclarator; - class ParsingFieldDeclarator; - class ColonProtectionRAIIObject; - class InMessageExpressionRAIIObject; - class PoisonSEHIdentifiersRAIIObject; - class OMPClause; - class OpenACCClause; - class ObjCTypeParamList; - struct OMPTraitProperty; - struct OMPTraitSelector; - struct OMPTraitSet; - class OMPTraitInfo; +class PragmaHandler; +class Scope; +class BalancedDelimiterTracker; +class CorrectionCandidateCallback; +class DeclGroupRef; +class DiagnosticBuilder; +struct LoopHint; +class Parser; +class ParsingDeclRAIIObject; +class ParsingDeclSpec; +class ParsingDeclarator; +class ParsingFieldDeclarator; +class ColonProtectionRAIIObject; +class InMessageExpressionRAIIObject; +class PoisonSEHIdentifiersRAIIObject; +class OMPClause; +class OpenACCClause; +class ObjCTypeParamList; +struct OMPTraitProperty; +struct OMPTraitSelector; +struct OMPTraitSet; +class OMPTraitInfo; /// Parser - This implements a parser for the C family of languages. After /// parsing units of the grammar, productions are invoked to handle whatever has @@ -99,17 +99,14 @@ class Parser : public CodeCompletionHandler { /// Identifiers used for SEH handling in Borland. These are only /// allowed in particular circumstances // __except block - IdentifierInfo *Ident__exception_code, - *Ident___exception_code, - *Ident_GetExceptionCode; + IdentifierInfo *Ident__exception_code, *Ident___exception_code, + *Ident_GetExceptionCode; // __except filter expression - IdentifierInfo *Ident__exception_info, - *Ident___exception_info, - *Ident_GetExceptionInfo; + IdentifierInfo *Ident__exception_info, *Ident___exception_info, + *Ident_GetExceptionInfo; // __finally - IdentifierInfo *Ident__abnormal_termination, - *Ident___abnormal_termination, - *Ident_AbnormalTermination; + IdentifierInfo *Ident__abnormal_termination, *Ident___abnormal_termination, + *Ident_AbnormalTermination; /// Contextual keywords for Microsoft extensions. IdentifierInfo *Ident__except; @@ -286,13 +283,12 @@ class Parser : public CodeCompletionHandler { class TemplateParameterDepthRAII { unsigned &Depth; unsigned AddedLevels; + public: explicit TemplateParameterDepthRAII(unsigned &Depth) - : Depth(Depth), AddedLevels(0) {} + : Depth(Depth), AddedLevels(0) {} - ~TemplateParameterDepthRAII() { - Depth -= AddedLevels; - } + ~TemplateParameterDepthRAII() { Depth -= AddedLevels; } void operator++() { ++Depth; @@ -421,8 +417,8 @@ class Parser : public CodeCompletionHandler { Locs.back().Priority = Prio; } } else { - Locs.push_back({TemplateName, LessLoc, Prio, - P.ParenCount, P.BracketCount, P.BraceCount}); + Locs.push_back({TemplateName, LessLoc, Prio, P.ParenCount, + P.BracketCount, P.BraceCount}); } } @@ -590,7 +586,6 @@ class Parser : public CodeCompletionHandler { return ConsumeToken(); } - SourceLocation getEndOfPreviousToken() { return PP.getLocForEndOfToken(PrevTokLocation); } @@ -607,17 +602,13 @@ class Parser : public CodeCompletionHandler { // /// isTokenParen - Return true if the cur token is '(' or ')'. - bool isTokenParen() const { - return Tok.isOneOf(tok::l_paren, tok::r_paren); - } + bool isTokenParen() const { return Tok.isOneOf(tok::l_paren, tok::r_paren); } /// isTokenBracket - Return true if the cur token is '[' or ']'. bool isTokenBracket() const { return Tok.isOneOf(tok::l_square, tok::r_square); } /// isTokenBrace - Return true if the cur token is '{' or '}'. - bool isTokenBrace() const { - return Tok.isOneOf(tok::l_brace, tok::r_brace); - } + bool isTokenBrace() const { return Tok.isOneOf(tok::l_brace, tok::r_brace); } /// isTokenStringLiteral - True if this token is a string-literal. bool isTokenStringLiteral() const { return tok::isStringLiteral(Tok.getKind()); @@ -635,10 +626,10 @@ class Parser : public CodeCompletionHandler { /// Return the current token to the token stream and make the given /// token the current token. void UnconsumeToken(Token &Consumed) { - Token Next = Tok; - PP.EnterToken(Consumed, /*IsReinject*/true); - PP.Lex(Tok); - PP.EnterToken(Next, /*IsReinject*/true); + Token Next = Tok; + PP.EnterToken(Consumed, /*IsReinject*/ true); + PP.Lex(Tok); + PP.EnterToken(Next, /*IsReinject*/ true); } SourceLocation ConsumeAnnotationToken() { @@ -657,7 +648,7 @@ class Parser : public CodeCompletionHandler { ++ParenCount; else if (ParenCount) { AngleBrackets.clear(*this); - --ParenCount; // Don't let unbalanced )'s drive the count negative. + --ParenCount; // Don't let unbalanced )'s drive the count negative. } PrevTokLocation = Tok.getLocation(); PP.Lex(Tok); @@ -672,7 +663,7 @@ class Parser : public CodeCompletionHandler { ++BracketCount; else if (BracketCount) { AngleBrackets.clear(*this); - --BracketCount; // Don't let unbalanced ]'s drive the count negative. + --BracketCount; // Don't let unbalanced ]'s drive the count negative. } PrevTokLocation = Tok.getLocation(); @@ -688,7 +679,7 @@ class Parser : public CodeCompletionHandler { ++BraceCount; else if (BraceCount) { AngleBrackets.clear(*this); - --BraceCount; // Don't let unbalanced }'s drive the count negative. + --BraceCount; // Don't let unbalanced }'s drive the count negative. } PrevTokLocation = Tok.getLocation(); @@ -862,16 +853,15 @@ class Parser : public CodeCompletionHandler { /// the Parser always has one token lexed that the preprocessor doesn't. /// const Token &GetLookAheadToken(unsigned N) { - if (N == 0 || Tok.is(tok::eof)) return Tok; - return PP.LookAhead(N-1); + if (N == 0 || Tok.is(tok::eof)) + return Tok; + return PP.LookAhead(N - 1); } public: /// NextToken - This peeks ahead one token and returns it without /// consuming it. - const Token &NextToken() { - return PP.LookAhead(0); - } + const Token &NextToken() { return PP.LookAhead(0); } /// getTypeAnnotation - Read a parsed type out of an annotation token. static TypeResult getTypeAnnotation(const Token &Tok) { @@ -888,7 +878,7 @@ class Parser : public CodeCompletionHandler { } static NamedDecl *getNonTypeAnnotation(const Token &Tok) { - return static_cast(Tok.getAnnotationValue()); + return static_cast(Tok.getAnnotationValue()); } static void setNonTypeAnnotation(Token &Tok, NamedDecl *ND) { @@ -896,7 +886,7 @@ class Parser : public CodeCompletionHandler { } static IdentifierInfo *getIdentifierAnnotation(const Token &Tok) { - return static_cast(Tok.getAnnotationValue()); + return static_cast(Tok.getAnnotationValue()); } static void setIdentifierAnnotation(Token &Tok, IdentifierInfo *ND) { @@ -962,9 +952,8 @@ class Parser : public CodeCompletionHandler { /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens, /// replacing them with the non-context-sensitive keywords. This returns /// true if the token was replaced. - bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc, - const char *&PrevSpec, unsigned &DiagID, - bool &isInvalid) { + bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID, bool &isInvalid) { if (!getLangOpts().AltiVec && !getLangOpts().ZVector) return false; @@ -982,7 +971,8 @@ class Parser : public CodeCompletionHandler { /// This returns true if the token was replaced. bool TryAltiVecVectorToken() { if ((!getLangOpts().AltiVec && !getLangOpts().ZVector) || - Tok.getIdentifierInfo() != Ident_vector) return false; + Tok.getIdentifierInfo() != Ident_vector) + return false; return TryAltiVecVectorTokenOutOfLine(); } @@ -1086,10 +1076,11 @@ class Parser : public CodeCompletionHandler { Parser &P; ObjCContainerDecl *DC; SaveAndRestore WithinObjCContainer; + public: explicit ObjCDeclContextSwitch(Parser &p) - : P(p), DC(p.getObjCDeclContext()), - WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) { + : P(p), DC(p.getObjCDeclContext()), + WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) { if (DC) P.Actions.ObjC().ActOnObjCTemporaryExitContainerContext(DC); } @@ -1116,7 +1107,7 @@ class Parser : public CodeCompletionHandler { /// If the next token is not a semicolon, this emits the specified diagnostic, /// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior /// to the semicolon, consumes that extra token. - bool ExpectAndConsumeSemi(unsigned DiagID , StringRef TokenUsed = ""); + bool ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed = ""); /// The kind of extra semi diagnostic to emit. enum ExtraSemiKind { @@ -1179,7 +1170,7 @@ class Parser : public CodeCompletionHandler { // ScopeFlags, but only when we aren't about to enter a compound statement. ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true, bool BeforeCompoundStmt = false) - : Self(Self) { + : Self(Self) { if (EnteredScope && !BeforeCompoundStmt) Self->EnterScope(ScopeFlags); else { @@ -1199,9 +1190,7 @@ class Parser : public CodeCompletionHandler { } } - ~ParseScope() { - Exit(); - } + ~ParseScope() { Exit(); } }; /// Introduces zero or more scopes for parsing. The scopes will all be exited @@ -1210,7 +1199,7 @@ class Parser : public CodeCompletionHandler { Parser &Self; unsigned NumScopes = 0; - MultiParseScope(const MultiParseScope&) = delete; + MultiParseScope(const MultiParseScope &) = delete; public: MultiParseScope(Parser &Self) : Self(Self) {} @@ -1224,9 +1213,7 @@ class Parser : public CodeCompletionHandler { --NumScopes; } } - ~MultiParseScope() { - Exit(); - } + ~MultiParseScope() { Exit(); } }; /// EnterScope - Start a new scope. @@ -1257,9 +1244,7 @@ class Parser : public CodeCompletionHandler { public: DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID); DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID); - DiagnosticBuilder Diag(unsigned DiagID) { - return Diag(Tok, DiagID); - } + DiagnosticBuilder Diag(unsigned DiagID) { return Diag(Tok, DiagID); } private: void SuggestParentheses(SourceLocation Loc, unsigned DK, @@ -1267,10 +1252,9 @@ class Parser : public CodeCompletionHandler { void CheckNestedObjCContexts(SourceLocation AtLoc); public: - /// Control flags for SkipUntil functions. enum SkipUntilFlags { - StopAtSemi = 1 << 0, ///< Stop skipping at semicolon + StopAtSemi = 1 << 0, ///< Stop skipping at semicolon /// Stop skipping at specified token, but don't skip the token itself StopBeforeMatch = 1 << 1, StopAtCodeCompletion = 1 << 2 ///< Stop at code completion @@ -1376,11 +1360,11 @@ class Parser : public CodeCompletionHandler { IdentifierInfo &AttrName; IdentifierInfo *MacroII = nullptr; SourceLocation AttrNameLoc; - SmallVector Decls; + SmallVector Decls; explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name, SourceLocation Loc) - : Self(P), AttrName(Name), AttrNameLoc(Loc) {} + : Self(P), AttrName(Name), AttrNameLoc(Loc) {} void ParseLexedAttributes() override; @@ -1408,7 +1392,7 @@ class Parser : public CodeCompletionHandler { }; // A list of late-parsed attributes. Used by ParseGNUAttributes. - class LateParsedAttrList: public SmallVector { + class LateParsedAttrList : public SmallVector { public: LateParsedAttrList(bool PSoon = false, bool LateAttrParseExperimentalExtOnly = false) @@ -1445,9 +1429,9 @@ class Parser : public CodeCompletionHandler { /// occurs within a member function declaration inside the class /// (C++ [class.mem]p2). struct LateParsedDefaultArgument { - explicit LateParsedDefaultArgument(Decl *P, - std::unique_ptr Toks = nullptr) - : Param(P), Toks(std::move(Toks)) { } + explicit LateParsedDefaultArgument( + Decl *P, std::unique_ptr Toks = nullptr) + : Param(P), Toks(std::move(Toks)) {} /// Param - The parameter declaration for this parameter. Decl *Param; @@ -1490,8 +1474,7 @@ class Parser : public CodeCompletionHandler { /// member whose parsing must to be delayed until the class is completely /// defined (C++11 [class.mem]p2). struct LateParsedMemberInitializer : public LateParsedDeclaration { - LateParsedMemberInitializer(Parser *P, Decl *FD) - : Self(P), Field(FD) { } + LateParsedMemberInitializer(Parser *P, Decl *FD) : Self(P), Field(FD) {} void ParseLexedMemberInitializers() override; @@ -1511,7 +1494,8 @@ class Parser : public CodeCompletionHandler { /// the method declarations and possibly attached inline definitions /// will be stored here with the tokens that will be parsed to create those /// entities. - typedef SmallVector LateParsedDeclarationsContainer; + typedef SmallVector + LateParsedDeclarationsContainer; /// Representation of a class that has been parsed, including /// any member function declarations or definitions that need to be @@ -1556,8 +1540,8 @@ class Parser : public CodeCompletionHandler { public: ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface) - : P(P), Popped(false), - State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) { + : P(P), Popped(false), + State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) { } /// Pop this class of the stack. @@ -1582,15 +1566,15 @@ class Parser : public CodeCompletionHandler { ParsedTemplateInfo(TemplateParameterLists *TemplateParams, bool isSpecialization, bool lastParameterListWasEmpty = false) - : Kind(isSpecialization? ExplicitSpecialization : Template), - TemplateParams(TemplateParams), - LastParameterListWasEmpty(lastParameterListWasEmpty) { } + : Kind(isSpecialization ? ExplicitSpecialization : Template), + TemplateParams(TemplateParams), + LastParameterListWasEmpty(lastParameterListWasEmpty) {} explicit ParsedTemplateInfo(SourceLocation ExternLoc, SourceLocation TemplateLoc) - : Kind(ExplicitInstantiation), TemplateParams(nullptr), - ExternLoc(ExternLoc), TemplateLoc(TemplateLoc), - LastParameterListWasEmpty(false){ } + : Kind(ExplicitInstantiation), TemplateParams(nullptr), + ExternLoc(ExternLoc), TemplateLoc(TemplateLoc), + LastParameterListWasEmpty(false) {} /// The kind of template we are parsing. enum { @@ -1636,10 +1620,7 @@ class Parser : public CodeCompletionHandler { void DeallocateParsedClasses(ParsingClass *Class); void PopParsingClass(Sema::ParsingClassState); - enum CachedInitKind { - CIK_DefaultArgument, - CIK_DefaultInitializer - }; + enum CachedInitKind { CIK_DefaultArgument, CIK_DefaultInitializer }; NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS, const ParsedAttributesView &AccessAttrs, @@ -1655,8 +1636,8 @@ class Parser : public CodeCompletionHandler { bool EnterScope, bool OnDefinition); void ParseLexedCAttributeList(LateParsedAttrList &LA, bool EnterScope, ParsedAttributes *OutAttrs = nullptr); - void ParseLexedAttribute(LateParsedAttribute &LA, - bool EnterScope, bool OnDefinition); + void ParseLexedAttribute(LateParsedAttribute &LA, bool EnterScope, + bool OnDefinition); void ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope, ParsedAttributes *OutAttrs = nullptr); void ParseLexedMethodDeclarations(ParsingClass &Class); @@ -1671,15 +1652,13 @@ class Parser : public CodeCompletionHandler { bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks); bool ConsumeAndStoreInitializer(CachedTokens &Toks, CachedInitKind CIK); bool ConsumeAndStoreConditional(CachedTokens &Toks); - bool ConsumeAndStoreUntil(tok::TokenKind T1, - CachedTokens &Toks, + bool ConsumeAndStoreUntil(tok::TokenKind T1, CachedTokens &Toks, bool StopAtSemi = true, bool ConsumeFinalToken = true) { return ConsumeAndStoreUntil(T1, T1, Toks, StopAtSemi, ConsumeFinalToken); } bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, - CachedTokens &Toks, - bool StopAtSemi = true, + CachedTokens &Toks, bool StopAtSemi = true, bool ConsumeFinalToken = true); //===--------------------------------------------------------------------===// @@ -1698,9 +1677,10 @@ class Parser : public CodeCompletionHandler { AccessSpecifier AS); void SkipFunctionBody(); - Decl *ParseFunctionDefinition(ParsingDeclarator &D, - const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), - LateParsedAttrList *LateParsedAttrs = nullptr); + Decl *ParseFunctionDefinition( + ParsingDeclarator &D, + const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), + LateParsedAttrList *LateParsedAttrs = nullptr); void ParseKNRParamDeclarations(Declarator &D); // EndLoc is filled with the location of the last token of the simple-asm. ExprResult ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc); @@ -1728,41 +1708,30 @@ class Parser : public CodeCompletionHandler { void ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl, tok::ObjCKeywordKind visibility, SourceLocation atLoc); - bool ParseObjCProtocolReferences(SmallVectorImpl &P, - SmallVectorImpl &PLocs, - bool WarnOnDeclarations, - bool ForObjCContainer, - SourceLocation &LAngleLoc, - SourceLocation &EndProtoLoc, - bool consumeLastToken); + bool ParseObjCProtocolReferences( + SmallVectorImpl &P, SmallVectorImpl &PLocs, + bool WarnOnDeclarations, bool ForObjCContainer, SourceLocation &LAngleLoc, + SourceLocation &EndProtoLoc, bool consumeLastToken); /// Parse the first angle-bracket-delimited clause for an /// Objective-C object or object pointer type, which may be either /// type arguments or protocol qualifiers. void parseObjCTypeArgsOrProtocolQualifiers( - ParsedType baseType, - SourceLocation &typeArgsLAngleLoc, - SmallVectorImpl &typeArgs, - SourceLocation &typeArgsRAngleLoc, - SourceLocation &protocolLAngleLoc, - SmallVectorImpl &protocols, - SmallVectorImpl &protocolLocs, - SourceLocation &protocolRAngleLoc, - bool consumeLastToken, - bool warnOnIncompleteProtocols); + ParsedType baseType, SourceLocation &typeArgsLAngleLoc, + SmallVectorImpl &typeArgs, SourceLocation &typeArgsRAngleLoc, + SourceLocation &protocolLAngleLoc, SmallVectorImpl &protocols, + SmallVectorImpl &protocolLocs, + SourceLocation &protocolRAngleLoc, bool consumeLastToken, + bool warnOnIncompleteProtocols); /// Parse either Objective-C type arguments or protocol qualifiers; if the /// former, also parse protocol qualifiers afterward. void parseObjCTypeArgsAndProtocolQualifiers( - ParsedType baseType, - SourceLocation &typeArgsLAngleLoc, - SmallVectorImpl &typeArgs, - SourceLocation &typeArgsRAngleLoc, - SourceLocation &protocolLAngleLoc, - SmallVectorImpl &protocols, - SmallVectorImpl &protocolLocs, - SourceLocation &protocolRAngleLoc, - bool consumeLastToken); + ParsedType baseType, SourceLocation &typeArgsLAngleLoc, + SmallVectorImpl &typeArgs, SourceLocation &typeArgsRAngleLoc, + SourceLocation &protocolLAngleLoc, SmallVectorImpl &protocols, + SmallVectorImpl &protocolLocs, + SourceLocation &protocolRAngleLoc, bool consumeLastToken); /// Parse a protocol qualifier type such as '', which is /// an anachronistic way of writing 'id'. @@ -1775,8 +1744,7 @@ class Parser : public CodeCompletionHandler { bool consumeLastToken, SourceLocation &endLoc); - void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, - Decl *CDecl); + void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, Decl *CDecl); DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc, ParsedAttributes &prefixAttrs); @@ -1784,11 +1752,11 @@ class Parser : public CodeCompletionHandler { Parser &P; Decl *Dcl; bool HasCFunction; - typedef SmallVector LateParsedObjCMethodContainer; + typedef SmallVector LateParsedObjCMethodContainer; LateParsedObjCMethodContainer LateParsedObjCMethods; ObjCImplParsingDataRAII(Parser &parser, Decl *D) - : P(parser), Dcl(D), HasCFunction(false) { + : P(parser), Dcl(D), HasCFunction(false) { P.CurParsedObjCImpl = this; Finished = false; } @@ -1813,8 +1781,15 @@ class Parser : public CodeCompletionHandler { IdentifierInfo *ParseObjCSelectorPiece(SourceLocation &MethodLocation); // Definitions for Objective-c context sensitive keywords recognition. enum ObjCTypeQual { - objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref, - objc_nonnull, objc_nullable, objc_null_unspecified, + objc_in = 0, + objc_out, + objc_inout, + objc_oneway, + objc_bycopy, + objc_byref, + objc_nonnull, + objc_nullable, + objc_null_unspecified, objc_NumQuals }; IdentifierInfo *ObjCTypeQuals[objc_NumQuals]; @@ -1824,11 +1799,12 @@ class Parser : public CodeCompletionHandler { ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, DeclaratorContext Ctx, ParsedAttributes *ParamAttrs); Decl *ParseObjCMethodPrototype( - tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword, - bool MethodDefinition = true); - Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType, - tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword, - bool MethodDefinition=true); + tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword, + bool MethodDefinition = true); + Decl *ParseObjCMethodDecl( + SourceLocation mLoc, tok::TokenKind mType, + tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword, + bool MethodDefinition = true); void ParseObjCPropertyAttribute(ObjCDeclSpec &DS); Decl *ParseObjCMethodDefinition(); @@ -1838,11 +1814,7 @@ class Parser : public CodeCompletionHandler { // C99 6.5: Expressions. /// TypeCastState - State whether an expression is or may be a type cast. - enum TypeCastState { - NotTypeCast = 0, - MaybeTypeCast, - IsTypeCast - }; + enum TypeCastState { NotTypeCast = 0, MaybeTypeCast, IsTypeCast }; ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast); ExprResult ParseConstantExpressionInExprEvalContext( @@ -1851,8 +1823,7 @@ class Parser : public CodeCompletionHandler { ExprResult ParseArrayBoundExpression(); ExprResult ParseCaseExpression(SourceLocation CaseLoc); ExprResult ParseConstraintExpression(); - ExprResult - ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause); + ExprResult ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause); ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause); // Expr that doesn't include commas. ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast); @@ -1873,21 +1844,15 @@ class Parser : public CodeCompletionHandler { ExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc); - ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, - prec::Level MinPrec); + ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec); /// Control what ParseCastExpression will parse. - enum CastParseKind { - AnyCastExpr = 0, - UnaryExprOnly, - PrimaryExprOnly - }; + enum CastParseKind { AnyCastExpr = 0, UnaryExprOnly, PrimaryExprOnly }; bool isRevertibleTypeTrait(const IdentifierInfo *Id, clang::tok::TokenKind *Kind = nullptr); ExprResult ParseCastExpression(CastParseKind ParseKind, - bool isAddressOfOperand, - bool &NotCastExpr, + bool isAddressOfOperand, bool &NotCastExpr, TypeCastState isTypeCast, bool isVectorLiteral = false, bool *NotPrimaryExpression = nullptr); @@ -1904,9 +1869,8 @@ class Parser : public CodeCompletionHandler { /// suffix. bool isPostfixExpressionSuffixStart() { tok::TokenKind K = Tok.getKind(); - return (K == tok::l_square || K == tok::l_paren || - K == tok::period || K == tok::arrow || - K == tok::plusplus || K == tok::minusminus); + return (K == tok::l_square || K == tok::l_paren || K == tok::period || + K == tok::arrow || K == tok::plusplus || K == tok::minusminus); } bool diagnoseUnknownTemplateId(ExprResult TemplateName, SourceLocation Less); @@ -1925,9 +1889,9 @@ class Parser : public CodeCompletionHandler { ExprResult ParseSYCLUniqueStableNameExpression(); ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, - bool &isCastExpr, - ParsedType &CastTy, - SourceRange &CastRange); + bool &isCastExpr, + ParsedType &CastTy, + SourceRange &CastRange); /// ParseExpressionList - Used for C/C++ (argument-)expression-list. bool ParseExpressionList(SmallVectorImpl &Exprs, @@ -1949,17 +1913,16 @@ class Parser : public CodeCompletionHandler { CastExpr // Also allow '(' type-name ')' }; ExprResult ParseParenExpression(ParenParseOption &ExprType, - bool stopIfCastExpr, - bool isTypeCast, - ParsedType &CastTy, - SourceLocation &RParenLoc); + bool stopIfCastExpr, bool isTypeCast, + ParsedType &CastTy, + SourceLocation &RParenLoc); ExprResult ParseCXXAmbiguousParenExpression( ParenParseOption &ExprType, ParsedType &CastTy, BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt); ExprResult ParseCompoundLiteralExpression(ParsedType Ty, - SourceLocation LParenLoc, - SourceLocation RParenLoc); + SourceLocation LParenLoc, + SourceLocation RParenLoc); ExprResult ParseGenericSelectionExpression(); @@ -2033,9 +1996,8 @@ class Parser : public CodeCompletionHandler { //===--------------------------------------------------------------------===// // C++ 5.2.4: C++ Pseudo-Destructor Expressions ExprResult ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc, - tok::TokenKind OpKind, - CXXScopeSpec &SS, - ParsedType ObjectType); + tok::TokenKind OpKind, CXXScopeSpec &SS, + ParsedType ObjectType); //===--------------------------------------------------------------------===// // C++ 9.3.2: C++ 'this' pointer @@ -2046,18 +2008,16 @@ class Parser : public CodeCompletionHandler { ExprResult ParseThrowExpression(); ExceptionSpecificationType tryParseExceptionSpecification( - bool Delayed, - SourceRange &SpecificationRange, - SmallVectorImpl &DynamicExceptions, - SmallVectorImpl &DynamicExceptionRanges, - ExprResult &NoexceptExpr, - CachedTokens *&ExceptionSpecTokens); + bool Delayed, SourceRange &SpecificationRange, + SmallVectorImpl &DynamicExceptions, + SmallVectorImpl &DynamicExceptionRanges, + ExprResult &NoexceptExpr, CachedTokens *&ExceptionSpecTokens); // EndLoc is filled with the location of the last token of the specification. - ExceptionSpecificationType ParseDynamicExceptionSpecification( - SourceRange &SpecificationRange, - SmallVectorImpl &Exceptions, - SmallVectorImpl &Ranges); + ExceptionSpecificationType + ParseDynamicExceptionSpecification(SourceRange &SpecificationRange, + SmallVectorImpl &Exceptions, + SmallVectorImpl &Ranges); //===--------------------------------------------------------------------===// // C++0x 8: Function declaration trailing-return-type @@ -2082,12 +2042,11 @@ class Parser : public CodeCompletionHandler { //===--------------------------------------------------------------------===// // C++ 5.3.4 and 5.3.5: C++ new and delete - bool ParseExpressionListOrTypeId(SmallVectorImpl &Exprs, + bool ParseExpressionListOrTypeId(SmallVectorImpl &Exprs, Declarator &D); void ParseDirectNewDeclarator(Declarator &D); ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start); - ExprResult ParseCXXDeleteExpression(bool UseGlobal, - SourceLocation Start); + ExprResult ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start); //===--------------------------------------------------------------------===// // C++ if/switch/while/for condition expression. @@ -2137,7 +2096,7 @@ class Parser : public CodeCompletionHandler { //===--------------------------------------------------------------------===// // clang Expressions - ExprResult ParseBlockLiteralExpression(); // ^{...} + ExprResult ParseBlockLiteralExpression(); // ^{...} //===--------------------------------------------------------------------===// // Objective-C Expressions @@ -2159,22 +2118,22 @@ class Parser : public CodeCompletionHandler { ParsedType ReceiverType, Expr *ReceiverExpr); ExprResult ParseAssignmentExprWithObjCMessageExprStart( - SourceLocation LBracloc, SourceLocation SuperLoc, - ParsedType ReceiverType, Expr *ReceiverExpr); + SourceLocation LBracloc, SourceLocation SuperLoc, ParsedType ReceiverType, + Expr *ReceiverExpr); bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr); //===--------------------------------------------------------------------===// // C99 6.8: Statements and Blocks. /// A SmallVector of expressions. - typedef SmallVector ExprVector; + typedef SmallVector ExprVector; StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr, ParsedStmtContext StmtCtx = ParsedStmtContext::SubStmt); - StmtResult ParseStatementOrDeclaration( - StmtVector &Stmts, ParsedStmtContext StmtCtx, - SourceLocation *TrailingElseLoc = nullptr); + StmtResult + ParseStatementOrDeclaration(StmtVector &Stmts, ParsedStmtContext StmtCtx, + SourceLocation *TrailingElseLoc = nullptr); StmtResult ParseStatementOrDeclarationAfterAttributes( StmtVector &Stmts, ParsedStmtContext StmtCtx, SourceLocation *TrailingElseLoc, ParsedAttributes &DeclAttrs, @@ -2187,8 +2146,7 @@ class Parser : public CodeCompletionHandler { ExprResult Expr = ExprResult()); StmtResult ParseDefaultStatement(ParsedStmtContext StmtCtx); StmtResult ParseCompoundStatement(bool isStmtExpr = false); - StmtResult ParseCompoundStatement(bool isStmtExpr, - unsigned ScopeFlags); + StmtResult ParseCompoundStatement(bool isStmtExpr, unsigned ScopeFlags); void ParseCompoundStatementLeadingPragmas(); void DiagnoseLabelAtEndOfCompoundStatement(); bool ConsumeNullStmt(StmtVector &Stmts); @@ -2198,6 +2156,7 @@ class Parser : public CodeCompletionHandler { SourceLocation Loc, Sema::ConditionKind CK, SourceLocation &LParenLoc, SourceLocation &RParenLoc); + StmtResult ParseWhenStatement(SourceLocation *TrailingElseLoc); StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc); StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc); StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc); @@ -2245,7 +2204,7 @@ class Parser : public CodeCompletionHandler { IfExistsBehavior Behavior; }; - bool ParseMicrosoftIfExistsCondition(IfExistsCondition& Result); + bool ParseMicrosoftIfExistsCondition(IfExistsCondition &Result); void ParseMicrosoftIfExistsStatement(StmtVector &Stmts); void ParseMicrosoftIfExistsExternalDeclaration(); void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, @@ -2282,7 +2241,6 @@ class Parser : public CodeCompletionHandler { StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc); StmtResult ParseObjCAutoreleasePoolStmt(SourceLocation atLoc); - //===--------------------------------------------------------------------===// // C99 6.7: Declarations. @@ -2485,8 +2443,9 @@ class Parser : public CodeCompletionHandler { ParsedTemplateInfo &TemplateInfo, SourceLocation *DeclEnd = nullptr, ForRangeInit *FRI = nullptr); - Decl *ParseDeclarationAfterDeclarator(Declarator &D, - const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); + Decl *ParseDeclarationAfterDeclarator( + Declarator &D, + const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); bool ParseAsmAttributesAfterDeclarator(Declarator &D); Decl *ParseDeclarationAfterDeclaratorAndAttributes( Declarator &D, @@ -2540,8 +2499,7 @@ class Parser : public CodeCompletionHandler { AccessSpecifier AS = AS_none, DeclSpecContext DSC = DeclSpecContext::DSC_normal); - void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, - DeclaratorContext Context); + void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, DeclaratorContext Context); void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo, @@ -2712,9 +2670,7 @@ class Parser : public CodeCompletionHandler { /// TPResult - Used as the result value for functions whose purpose is to /// disambiguate C++ constructs by "tentatively parsing" them. - enum class TPResult { - True, False, Ambiguous, Error - }; + enum class TPResult { True, False, Ambiguous, Error }; /// Determine whether we could have an enum-base. /// @@ -3178,9 +3134,10 @@ class Parser : public CodeCompletionHandler { CXXScopeSpec &SS; bool EnteredScope; bool CreatedScope; + public: DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss) - : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {} + : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {} void EnterDeclaratorScope() { assert(!EnteredScope && "Already entered the scope!"); @@ -3206,7 +3163,7 @@ class Parser : public CodeCompletionHandler { /// ParseDeclarator - Parse and verify a newly-initialized declarator. void ParseDeclarator(Declarator &D); /// A function that parses a variant of direct-declarator. - typedef void (Parser::*DirectDeclParseFunction)(Declarator&); + typedef void (Parser::*DirectDeclParseFunction)(Declarator &); void ParseDeclaratorInternal(Declarator &D, DirectDeclParseFunction DirectDeclParser); @@ -3216,11 +3173,10 @@ class Parser : public CodeCompletionHandler { AR_GNUAttributesParsed = 1 << 1, AR_CXX11AttributesParsed = 1 << 2, AR_DeclspecAttributesParsed = 1 << 3, - AR_AllAttributesParsed = AR_GNUAttributesParsed | - AR_CXX11AttributesParsed | + AR_AllAttributesParsed = AR_GNUAttributesParsed | AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed, - AR_VendorAttributesParsed = AR_GNUAttributesParsed | - AR_DeclspecAttributesParsed + AR_VendorAttributesParsed = + AR_GNUAttributesParsed | AR_DeclspecAttributesParsed }; void ParseTypeQualifierListOpt( @@ -3241,8 +3197,7 @@ class Parser : public CodeCompletionHandler { SourceLocation &RefQualifierLoc); bool isFunctionDeclaratorIdentifierList(); void ParseFunctionDeclaratorIdentifierList( - Declarator &D, - SmallVectorImpl &ParamInfo); + Declarator &D, SmallVectorImpl &ParamInfo); void ParseParameterDeclarationClause( Declarator &D, ParsedAttributes &attrs, SmallVectorImpl &ParamInfo, @@ -3302,10 +3257,8 @@ class Parser : public CodeCompletionHandler { DeclGroupPtrTy ParseUsingDirectiveOrDeclaration( DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo, SourceLocation &DeclEnd, ParsedAttributes &Attrs); - Decl *ParseUsingDirective(DeclaratorContext Context, - SourceLocation UsingLoc, - SourceLocation &DeclEnd, - ParsedAttributes &attrs); + Decl *ParseUsingDirective(DeclaratorContext Context, SourceLocation UsingLoc, + SourceLocation &DeclEnd, ParsedAttributes &attrs); struct UsingDeclarator { SourceLocation TypenameLoc; @@ -3345,8 +3298,7 @@ class Parser : public CodeCompletionHandler { AccessSpecifier AS, bool EnteringContext, DeclSpecContext DSC, ParsedAttributes &Attributes); void SkipCXXMemberSpecification(SourceLocation StartLoc, - SourceLocation AttrFixitLoc, - unsigned TagType, + SourceLocation AttrFixitLoc, unsigned TagType, Decl *TagDecl); void ParseCXXMemberSpecification(SourceLocation StartLoc, SourceLocation AttrFixitLoc, @@ -3354,13 +3306,13 @@ class Parser : public CodeCompletionHandler { Decl *TagDecl); ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction, SourceLocation &EqualLoc); - bool - ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo, - VirtSpecifiers &VS, - ExprResult &BitfieldSize, - LateParsedAttrList &LateAttrs); - void MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D, - VirtSpecifiers &VS); + bool ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo, + VirtSpecifiers &VS, + ExprResult &BitfieldSize, + LateParsedAttrList &LateAttrs); + void + MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D, + VirtSpecifiers &VS); DeclGroupPtrTy ParseCXXClassMemberDeclaration( AccessSpecifier AS, ParsedAttributes &Attr, ParsedTemplateInfo &TemplateInfo, @@ -3371,7 +3323,7 @@ class Parser : public CodeCompletionHandler { DeclSpec::TST TagType, Decl *Tag); void ParseConstructorInitializer(Decl *ConstructorDecl); MemInitResult ParseMemInitializer(Decl *ConstructorDecl); - void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, + void HandleMemberFunctionDeclDelays(Declarator &DeclaratorInfo, Decl *ThisDecl); //===--------------------------------------------------------------------===// @@ -3382,18 +3334,15 @@ class Parser : public CodeCompletionHandler { BaseResult ParseBaseSpecifier(Decl *ClassDecl); AccessSpecifier getAccessSpecifierIfPresent() const; - bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, - ParsedType ObjectType, + bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, SourceLocation TemplateKWLoc, IdentifierInfo *Name, SourceLocation NameLoc, - bool EnteringContext, - UnqualifiedId &Id, + bool EnteringContext, UnqualifiedId &Id, bool AssumeTemplateId); bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, - ParsedType ObjectType, - UnqualifiedId &Result); + ParsedType ObjectType, UnqualifiedId &Result); //===--------------------------------------------------------------------===// // OpenMP: Directives and clauses. @@ -3482,8 +3431,7 @@ class Parser : public CodeCompletionHandler { void parseOMPEndDirective(OpenMPDirectiveKind BeginKind, OpenMPDirectiveKind ExpectedKind, OpenMPDirectiveKind FoundKind, - SourceLocation MatchingLoc, - SourceLocation FoundLoc, + SourceLocation MatchingLoc, SourceLocation FoundLoc, bool SkipUntilOpenMPEnd); /// Parses declarative OpenMP directives. @@ -3517,8 +3465,8 @@ class Parser : public CodeCompletionHandler { /// bool ParseOpenMPSimpleVarList( OpenMPDirectiveKind Kind, - const llvm::function_ref & - Callback, + const llvm::function_ref + &Callback, bool AllowScopeSpecifier); /// Parses declarative or executable directive. /// @@ -3566,8 +3514,7 @@ class Parser : public CodeCompletionHandler { /// \param ParseOnly true to skip the clause's semantic actions and return /// nullptr. /// - OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, - bool ParseOnly); + OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, bool ParseOnly); /// Parses simple clause of a kind \a Kind. /// /// \param Kind Kind of current clause. @@ -3830,7 +3777,7 @@ class Parser : public CodeCompletionHandler { SourceLocation &LAngleLoc, SourceLocation &RAngleLoc); bool ParseTemplateParameterList(unsigned Depth, - SmallVectorImpl &TemplateParams); + SmallVectorImpl &TemplateParams); TPResult isStartOfTemplateTypeParameter(); NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position); NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position); @@ -3858,8 +3805,7 @@ class Parser : public CodeCompletionHandler { TemplateTy NameHint = nullptr); bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, - CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, + CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &TemplateName, bool AllowTypeAnnotation = true, bool TypeConstraint = false); @@ -3878,9 +3824,8 @@ class Parser : public CodeCompletionHandler { ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none); // C++2a: Template, concept definition [temp] - Decl * - ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo, - SourceLocation &DeclEnd); + Decl *ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo, + SourceLocation &DeclEnd); /// Parse the given string as a type. /// @@ -3941,9 +3886,9 @@ class Parser : public CodeCompletionHandler { public: enum AQ { AQ_unspecified = 0, - AQ_volatile = 1, - AQ_inline = 2, - AQ_goto = 4, + AQ_volatile = 1, + AQ_inline = 2, + AQ_goto = 4, }; static const char *getQualifierName(AQ Qualifier); bool setAsmQualifier(AQ Qualifier); @@ -3957,6 +3902,6 @@ class Parser : public CodeCompletionHandler { bool parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ); }; -} // end namespace clang +} // end namespace clang #endif diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d6f3508a5243f..dae5b0538134f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10683,6 +10683,9 @@ class Sema final : public SemaBase { SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal); + StmtResult ActOnWhenStatement(SourceLocation WhenLoc, ConditionResult Cond, bool IsAccept, + IdentifierInfo *VarName, SourceLocation VarLoc, + Stmt *Body); StmtResult BuildIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 8725d5455ec73..f123f13d7a996 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1551,6 +1551,9 @@ enum StmtCode { /// A WhileStmt record. STMT_WHILE, + /// A WhenStmt record. + STMT_WHEN, + /// A DoStmt record. STMT_DO, diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index fe59d6070b3e8..c3f7aec2de07e 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -1179,6 +1179,19 @@ void WhileStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) { DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd()); } +// When Stmt +WhenStmt* WhenStmt::Create(const ASTContext &Ctx, SourceLocation Loc, Expr *Cond, Stmt *BodyStmt) { +// WhenStmt* WhenStmt::Create(const ASTContext &Ctx, SourceLocation Loc, Expr *Cond, bool Accept, IdentifierInfo *Var, Stmt *BodyStmt) { + + void *Mem = Ctx.Allocate(totalSizeToAlloc(NumMandatoryStmtPtr), alignof(WhenStmt)); + return new (Mem) WhenStmt(Loc, Cond, BodyStmt); +} + +WhenStmt* WhenStmt::CreateEmpty(const ASTContext &Ctx) { + void *Mem = Ctx.Allocate(totalSizeToAlloc(NumMandatoryStmtPtr), alignof(WhenStmt)); + return new (Mem) WhenStmt(EmptyShell()); +} + // IndirectGotoStmt LabelDecl *IndirectGotoStmt::getConstantTarget() { if (auto *E = dyn_cast(getTarget()->IgnoreParenImpCasts())) diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 29f0276d7b7b0..b56bba204b65c 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -382,6 +382,13 @@ void StmtPrinter::VisitWhileStmt(WhileStmt *Node) { PrintStmt(Node->getBody()); } +void StmtPrinter::VisitWhenStmt(WhenStmt* Node){ + Indent() << "_When ("; + PrintExpr(Node->getCondition()); + OS << ") "; + PrintStmt(Node->getBody()); +} + void StmtPrinter::VisitDoStmt(DoStmt *Node) { Indent() << "do "; if (auto *CS = dyn_cast(Node->getBody())) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 3dfbef1cdb712..62f532b4ea807 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -295,6 +295,10 @@ void StmtProfiler::VisitWhileStmt(const WhileStmt *S) { VisitDecl(S->getConditionVariable()); } +void StmtProfiler::VisitWhenStmt(const WhenStmt *S) { + VisitStmt(S); +} + void StmtProfiler::VisitDoStmt(const DoStmt *S) { VisitStmt(S); } diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 820bb521ccf85..44b22e423f66c 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -412,6 +412,23 @@ struct MapRegionCounters : public RecursiveASTVisitor { Hash.combine(PGOHash::EndOfScope); return true; } + + bool TraverseWhenStmt(WhenStmt *When) { + bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage; + for (Stmt *CS : When->children()) { + if (!CS || NoSingleByteCoverage) + continue; + if (CS == When->getCondition()) + CounterMap[When->getCondition()] = NextCounter++; + else if (CS == When->getBody()) + CounterMap[When->getBody()] = NextCounter++; + } + + Base::TraverseWhenStmt(When); + if (Hash.getHashVersion() != PGO_HASH_V1) + Hash.combine(PGOHash::EndOfScope); + return true; + } bool TraverseDoStmt(DoStmt *Do) { // When single byte coverage mode is enabled, add a counter to condition and diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index f6d787a0c8831..d22d83d20f81c 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -28,6 +28,7 @@ #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/TypoCorrection.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/raw_ostream.h" #include using namespace clang; @@ -177,6 +178,7 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( StmtVector &Stmts, ParsedStmtContext StmtCtx, SourceLocation *TrailingElseLoc, ParsedAttributes &CXX11Attrs, ParsedAttributes &GNUAttrs) { + llvm::errs() << "ParseStatementOrDeclarationAfterAttributes\n"; const char *SemiError = nullptr; StmtResult Res; SourceLocation GNUAttributeLoc; @@ -321,6 +323,8 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( return Actions.ActOnNullStmt(ConsumeToken(), HasLeadingEmptyMacro); } + case tok::kw__When: // C99 6.8.4.1: if-statement + return ParseWhenStatement(TrailingElseLoc); case tok::kw_if: // C99 6.8.4.1: if-statement return ParseIfStatement(TrailingElseLoc); case tok::kw_switch: // C99 6.8.4.2: switch-statement @@ -1743,6 +1747,57 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { ThenStmt.get(), ElseLoc, ElseStmt.get()); } + +StmtResult Parser::ParseWhenStatement(SourceLocation *TrailingElseLoc) { + llvm::errs() << "Parsing _When statement\n"; + assert(Tok.is(tok::kw__When) && "Not a _When stmt!"); + SourceLocation WhenLoc = ConsumeToken(); // Eat `_When` + + if (Tok.isNot(tok::l_paren)) { + Diag(Tok, diag::err_expected_lparen_after) << "_When"; + return StmtError(); + } + + Sema::ConditionResult Cond; + SourceLocation LParen; + SourceLocation RParen; + if (ParseParenExprOrCondition(nullptr, Cond, WhenLoc, + Sema::ConditionKind::Boolean, LParen, RParen)) + return StmtError(); + + // // Parse either _Accept or _Select + // if (Tok.isNot(tok::_Accept) && Tok.isNot(tok::_Select)) { + // Diag(Tok, diag::err_expected_accept_or_select); + // return StmtError(); + // } + + // bool IsAccept = Tok.is(tok::_Accept); + // SourceLocation KeywordLoc = ConsumeToken(); // Eat `_Accept` or `_Select` + + // if (Tok.isNot(tok::identifier)) { + // Diag(Tok, diag::err_expected_variable); + // return StmtError(); + // } + + // IdentifierInfo *VarName = Tok.getIdentifierInfo(); + // SourceLocation VarLoc = ConsumeToken(); // Eat the variable name + + if (Tok.isNot(tok::l_brace)) + return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace); + + StmtResult Block(ParseCompoundStatement()); + + if(Block.isInvalid()) + return Block; + + IdentifierInfo *VarName = nullptr; + SourceLocation VarLoc; + bool IsAccept = false; + + return Actions.ActOnWhenStatement(WhenLoc, Cond, IsAccept, VarName, + VarLoc, Block.get()); +} + /// ParseSwitchStatement /// switch-statement: /// 'switch' '(' expression ')' statement diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index bfcdab91dd6f0..b7ca20c5cc79e 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1515,6 +1515,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Stmt::SEHTryStmtClass: case Stmt::SwitchStmtClass: case Stmt::WhileStmtClass: + case Stmt::WhenStmtClass: return canSubStmtsThrow(*this, S); case Stmt::DeclStmtClass: { diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 23720591fbde2..b822f6229efba 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -26,6 +26,7 @@ #include "clang/AST/StmtObjC.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeOrdering.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" @@ -50,6 +51,19 @@ using namespace clang; using namespace sema; +StmtResult Sema::ActOnWhenStatement(SourceLocation WhenLoc, ConditionResult Cond, bool IsAccept, + IdentifierInfo *VarName, SourceLocation VarLoc, Stmt *Body) { + if (Cond.isInvalid()) + return StmtError(); + + Expr *CondExpr = Cond.get().second; + if(!CondExpr) { + return StmtError(); + } + + return WhenStmt::Create(Context, WhenLoc, CondExpr, Body); +} + StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) { if (FE.isInvalid()) return StmtError(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 308faed3b95ad..ef5aefaf54358 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -57,11 +57,7 @@ using namespace clang; -enum TypeDiagSelector { - TDS_Function, - TDS_Pointer, - TDS_ObjCObjOrBlock -}; +enum TypeDiagSelector { TDS_Function, TDS_Pointer, TDS_ObjCObjOrBlock }; /// isOmittedBlockReturnType - Return true if this declarator is missing a /// return type because this is a omitted return type on a block literal. @@ -71,11 +67,11 @@ static bool isOmittedBlockReturnType(const Declarator &D) { return false; if (D.getNumTypeObjects() == 0) - return true; // ^{ ... } + return true; // ^{ ... } if (D.getNumTypeObjects() == 1 && D.getTypeObject(0).Kind == DeclaratorChunk::Function) - return true; // ^(int X, float Y) { ... } + return true; // ^(int X, float Y) { ... } return false; } @@ -104,13 +100,15 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr, StringRef name = attr.getAttrName()->getName(); // The GC attributes are usually written with macros; special-case them. - IdentifierInfo *II = attr.isArgIdent(0) ? attr.getArgAsIdent(0)->Ident - : nullptr; + IdentifierInfo *II = + attr.isArgIdent(0) ? attr.getArgAsIdent(0)->Ident : nullptr; if (useExpansionLoc && loc.isMacroID() && II) { if (II->isStr("strong")) { - if (S.findMacroSpelling(loc, "__strong")) name = "__strong"; + if (S.findMacroSpelling(loc, "__strong")) + name = "__strong"; } else if (II->isStr("weak")) { - if (S.findMacroSpelling(loc, "__weak")) name = "__weak"; + if (S.findMacroSpelling(loc, "__weak")) + name = "__weak"; } } @@ -185,197 +183,190 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr, case ParsedAttr::AT_TypeNullUnspecified namespace { - /// An object which stores processing state for the entire - /// GetTypeForDeclarator process. - class TypeProcessingState { - Sema &sema; - - /// The declarator being processed. - Declarator &declarator; - - /// The index of the declarator chunk we're currently processing. - /// May be the total number of valid chunks, indicating the - /// DeclSpec. - unsigned chunkIndex; - - /// The original set of attributes on the DeclSpec. - SmallVector savedAttrs; - - /// A list of attributes to diagnose the uselessness of when the - /// processing is complete. - SmallVector ignoredTypeAttrs; - - /// Attributes corresponding to AttributedTypeLocs that we have not yet - /// populated. - // FIXME: The two-phase mechanism by which we construct Types and fill - // their TypeLocs makes it hard to correctly assign these. We keep the - // attributes in creation order as an attempt to make them line up - // properly. - using TypeAttrPair = std::pair; - SmallVector AttrsForTypes; - bool AttrsForTypesSorted = true; - - /// MacroQualifiedTypes mapping to macro expansion locations that will be - /// stored in a MacroQualifiedTypeLoc. - llvm::DenseMap LocsForMacros; - - /// Flag to indicate we parsed a noderef attribute. This is used for - /// validating that noderef was used on a pointer or array. - bool parsedNoDeref; - - // Flag to indicate that we already parsed a HLSL parameter modifier - // attribute. This prevents double-mutating the type. - bool ParsedHLSLParamMod; +/// An object which stores processing state for the entire +/// GetTypeForDeclarator process. +class TypeProcessingState { + Sema &sema; - public: - TypeProcessingState(Sema &sema, Declarator &declarator) - : sema(sema), declarator(declarator), - chunkIndex(declarator.getNumTypeObjects()), parsedNoDeref(false), - ParsedHLSLParamMod(false) {} + /// The declarator being processed. + Declarator &declarator; - Sema &getSema() const { - return sema; - } + /// The index of the declarator chunk we're currently processing. + /// May be the total number of valid chunks, indicating the + /// DeclSpec. + unsigned chunkIndex; - Declarator &getDeclarator() const { - return declarator; - } + /// The original set of attributes on the DeclSpec. + SmallVector savedAttrs; - bool isProcessingDeclSpec() const { - return chunkIndex == declarator.getNumTypeObjects(); - } + /// A list of attributes to diagnose the uselessness of when the + /// processing is complete. + SmallVector ignoredTypeAttrs; - unsigned getCurrentChunkIndex() const { - return chunkIndex; - } + /// Attributes corresponding to AttributedTypeLocs that we have not yet + /// populated. + // FIXME: The two-phase mechanism by which we construct Types and fill + // their TypeLocs makes it hard to correctly assign these. We keep the + // attributes in creation order as an attempt to make them line up + // properly. + using TypeAttrPair = std::pair; + SmallVector AttrsForTypes; + bool AttrsForTypesSorted = true; - void setCurrentChunkIndex(unsigned idx) { - assert(idx <= declarator.getNumTypeObjects()); - chunkIndex = idx; - } + /// MacroQualifiedTypes mapping to macro expansion locations that will be + /// stored in a MacroQualifiedTypeLoc. + llvm::DenseMap LocsForMacros; - ParsedAttributesView &getCurrentAttributes() const { - if (isProcessingDeclSpec()) - return getMutableDeclSpec().getAttributes(); - return declarator.getTypeObject(chunkIndex).getAttrs(); - } + /// Flag to indicate we parsed a noderef attribute. This is used for + /// validating that noderef was used on a pointer or array. + bool parsedNoDeref; - /// Save the current set of attributes on the DeclSpec. - void saveDeclSpecAttrs() { - // Don't try to save them multiple times. - if (!savedAttrs.empty()) - return; + // Flag to indicate that we already parsed a HLSL parameter modifier + // attribute. This prevents double-mutating the type. + bool ParsedHLSLParamMod; - DeclSpec &spec = getMutableDeclSpec(); - llvm::append_range(savedAttrs, - llvm::make_pointer_range(spec.getAttributes())); - } +public: + TypeProcessingState(Sema &sema, Declarator &declarator) + : sema(sema), declarator(declarator), + chunkIndex(declarator.getNumTypeObjects()), parsedNoDeref(false), + ParsedHLSLParamMod(false) {} - /// Record that we had nowhere to put the given type attribute. - /// We will diagnose such attributes later. - void addIgnoredTypeAttr(ParsedAttr &attr) { - ignoredTypeAttrs.push_back(&attr); - } + Sema &getSema() const { return sema; } - /// Diagnose all the ignored type attributes, given that the - /// declarator worked out to the given type. - void diagnoseIgnoredTypeAttrs(QualType type) const { - for (auto *Attr : ignoredTypeAttrs) - diagnoseBadTypeAttribute(getSema(), *Attr, type); - } + Declarator &getDeclarator() const { return declarator; } - /// Get an attributed type for the given attribute, and remember the Attr - /// object so that we can attach it to the AttributedTypeLoc. - QualType getAttributedType(Attr *A, QualType ModifiedType, - QualType EquivType) { - QualType T = - sema.Context.getAttributedType(A, ModifiedType, EquivType); - AttrsForTypes.push_back({cast(T.getTypePtr()), A}); - AttrsForTypesSorted = false; - return T; - } + bool isProcessingDeclSpec() const { + return chunkIndex == declarator.getNumTypeObjects(); + } - /// Get a BTFTagAttributed type for the btf_type_tag attribute. - QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr, - QualType WrappedType) { - return sema.Context.getBTFTagAttributedType(BTFAttr, WrappedType); - } + unsigned getCurrentChunkIndex() const { return chunkIndex; } - /// Completely replace the \c auto in \p TypeWithAuto by - /// \p Replacement. Also replace \p TypeWithAuto in \c TypeAttrPair if - /// necessary. - QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement) { - QualType T = sema.ReplaceAutoType(TypeWithAuto, Replacement); - if (auto *AttrTy = TypeWithAuto->getAs()) { - // Attributed type still should be an attributed type after replacement. - auto *NewAttrTy = cast(T.getTypePtr()); - for (TypeAttrPair &A : AttrsForTypes) { - if (A.first == AttrTy) - A.first = NewAttrTy; - } - AttrsForTypesSorted = false; - } - return T; - } + void setCurrentChunkIndex(unsigned idx) { + assert(idx <= declarator.getNumTypeObjects()); + chunkIndex = idx; + } - /// Extract and remove the Attr* for a given attributed type. - const Attr *takeAttrForAttributedType(const AttributedType *AT) { - if (!AttrsForTypesSorted) { - llvm::stable_sort(AttrsForTypes, llvm::less_first()); - AttrsForTypesSorted = true; - } + ParsedAttributesView &getCurrentAttributes() const { + if (isProcessingDeclSpec()) + return getMutableDeclSpec().getAttributes(); + return declarator.getTypeObject(chunkIndex).getAttrs(); + } - // FIXME: This is quadratic if we have lots of reuses of the same - // attributed type. - for (auto It = std::partition_point( - AttrsForTypes.begin(), AttrsForTypes.end(), - [=](const TypeAttrPair &A) { return A.first < AT; }); - It != AttrsForTypes.end() && It->first == AT; ++It) { - if (It->second) { - const Attr *Result = It->second; - It->second = nullptr; - return Result; - } - } + /// Save the current set of attributes on the DeclSpec. + void saveDeclSpecAttrs() { + // Don't try to save them multiple times. + if (!savedAttrs.empty()) + return; + + DeclSpec &spec = getMutableDeclSpec(); + llvm::append_range(savedAttrs, + llvm::make_pointer_range(spec.getAttributes())); + } + + /// Record that we had nowhere to put the given type attribute. + /// We will diagnose such attributes later. + void addIgnoredTypeAttr(ParsedAttr &attr) { + ignoredTypeAttrs.push_back(&attr); + } + + /// Diagnose all the ignored type attributes, given that the + /// declarator worked out to the given type. + void diagnoseIgnoredTypeAttrs(QualType type) const { + for (auto *Attr : ignoredTypeAttrs) + diagnoseBadTypeAttribute(getSema(), *Attr, type); + } - llvm_unreachable("no Attr* for AttributedType*"); + /// Get an attributed type for the given attribute, and remember the Attr + /// object so that we can attach it to the AttributedTypeLoc. + QualType getAttributedType(Attr *A, QualType ModifiedType, + QualType EquivType) { + QualType T = sema.Context.getAttributedType(A, ModifiedType, EquivType); + AttrsForTypes.push_back({cast(T.getTypePtr()), A}); + AttrsForTypesSorted = false; + return T; + } + + /// Get a BTFTagAttributed type for the btf_type_tag attribute. + QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr, + QualType WrappedType) { + return sema.Context.getBTFTagAttributedType(BTFAttr, WrappedType); + } + + /// Completely replace the \c auto in \p TypeWithAuto by + /// \p Replacement. Also replace \p TypeWithAuto in \c TypeAttrPair if + /// necessary. + QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement) { + QualType T = sema.ReplaceAutoType(TypeWithAuto, Replacement); + if (auto *AttrTy = TypeWithAuto->getAs()) { + // Attributed type still should be an attributed type after replacement. + auto *NewAttrTy = cast(T.getTypePtr()); + for (TypeAttrPair &A : AttrsForTypes) { + if (A.first == AttrTy) + A.first = NewAttrTy; + } + AttrsForTypesSorted = false; } + return T; + } - SourceLocation - getExpansionLocForMacroQualifiedType(const MacroQualifiedType *MQT) const { - auto FoundLoc = LocsForMacros.find(MQT); - assert(FoundLoc != LocsForMacros.end() && - "Unable to find macro expansion location for MacroQualifedType"); - return FoundLoc->second; + /// Extract and remove the Attr* for a given attributed type. + const Attr *takeAttrForAttributedType(const AttributedType *AT) { + if (!AttrsForTypesSorted) { + llvm::stable_sort(AttrsForTypes, llvm::less_first()); + AttrsForTypesSorted = true; } - void setExpansionLocForMacroQualifiedType(const MacroQualifiedType *MQT, - SourceLocation Loc) { - LocsForMacros[MQT] = Loc; + // FIXME: This is quadratic if we have lots of reuses of the same + // attributed type. + for (auto It = std::partition_point( + AttrsForTypes.begin(), AttrsForTypes.end(), + [=](const TypeAttrPair &A) { return A.first < AT; }); + It != AttrsForTypes.end() && It->first == AT; ++It) { + if (It->second) { + const Attr *Result = It->second; + It->second = nullptr; + return Result; + } } - void setParsedNoDeref(bool parsed) { parsedNoDeref = parsed; } + llvm_unreachable("no Attr* for AttributedType*"); + } - bool didParseNoDeref() const { return parsedNoDeref; } + SourceLocation + getExpansionLocForMacroQualifiedType(const MacroQualifiedType *MQT) const { + auto FoundLoc = LocsForMacros.find(MQT); + assert(FoundLoc != LocsForMacros.end() && + "Unable to find macro expansion location for MacroQualifedType"); + return FoundLoc->second; + } - void setParsedHLSLParamMod(bool Parsed) { ParsedHLSLParamMod = Parsed; } + void setExpansionLocForMacroQualifiedType(const MacroQualifiedType *MQT, + SourceLocation Loc) { + LocsForMacros[MQT] = Loc; + } - bool didParseHLSLParamMod() const { return ParsedHLSLParamMod; } + void setParsedNoDeref(bool parsed) { parsedNoDeref = parsed; } - ~TypeProcessingState() { - if (savedAttrs.empty()) - return; + bool didParseNoDeref() const { return parsedNoDeref; } - getMutableDeclSpec().getAttributes().clearListOnly(); - for (ParsedAttr *AL : savedAttrs) - getMutableDeclSpec().getAttributes().addAtEnd(AL); - } + void setParsedHLSLParamMod(bool Parsed) { ParsedHLSLParamMod = Parsed; } - private: - DeclSpec &getMutableDeclSpec() const { - return const_cast(declarator.getDeclSpec()); - } - }; + bool didParseHLSLParamMod() const { return ParsedHLSLParamMod; } + + ~TypeProcessingState() { + if (savedAttrs.empty()) + return; + + getMutableDeclSpec().getAttributes().clearListOnly(); + for (ParsedAttr *AL : savedAttrs) + getMutableDeclSpec().getAttributes().addAtEnd(AL); + } + +private: + DeclSpec &getMutableDeclSpec() const { + return const_cast(declarator.getDeclSpec()); + } +}; } // end anonymous namespace static void moveAttrFromListToList(ParsedAttr &attr, @@ -438,7 +429,7 @@ static DeclaratorChunk *maybeMovePastReturnType(Declarator &declarator, // First, look inwards past parens for a function declarator. for (; i != 0; --i) { - DeclaratorChunk &fnChunk = declarator.getTypeObject(i-1); + DeclaratorChunk &fnChunk = declarator.getTypeObject(i - 1); switch (fnChunk.Kind) { case DeclaratorChunk::Paren: continue; @@ -456,7 +447,7 @@ static DeclaratorChunk *maybeMovePastReturnType(Declarator &declarator, // looking for a (block-)pointer declarator. case DeclaratorChunk::Function: for (--i; i != 0; --i) { - DeclaratorChunk &ptrChunk = declarator.getTypeObject(i-1); + DeclaratorChunk &ptrChunk = declarator.getTypeObject(i - 1); switch (ptrChunk.Kind) { case DeclaratorChunk::Paren: case DeclaratorChunk::Array: @@ -485,7 +476,7 @@ static DeclaratorChunk *maybeMovePastReturnType(Declarator &declarator, llvm_unreachable("bad declarator chunk kind"); // Okay, reconsider from our new point. - continue_outer: ; + continue_outer:; } // Ran out of chunks, bail out. @@ -503,7 +494,7 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state, // Move it to the outermost normal or block pointer declarator. for (unsigned i = state.getCurrentChunkIndex(); i != 0; --i) { - DeclaratorChunk &chunk = declarator.getTypeObject(i-1); + DeclaratorChunk &chunk = declarator.getTypeObject(i - 1); switch (chunk.Kind) { case DeclaratorChunk::Pointer: case DeclaratorChunk::BlockPointer: { @@ -514,7 +505,8 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state, attr.getKind() == ParsedAttr::AT_ObjCOwnership) destChunk = maybeMovePastReturnType(declarator, i - 1, /*onlyBlockPointers=*/true); - if (!destChunk) destChunk = &chunk; + if (!destChunk) + destChunk = &chunk; moveAttrFromListToList(attr, state.getCurrentAttributes(), destChunk->getAttrs()); @@ -529,9 +521,9 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state, case DeclaratorChunk::Function: if (state.isProcessingDeclSpec() && attr.getKind() == ParsedAttr::AT_ObjCOwnership) { - if (DeclaratorChunk *dest = maybeMovePastReturnType( - declarator, i, - /*onlyBlockPointers=*/true)) { + if (DeclaratorChunk *dest = + maybeMovePastReturnType(declarator, i, + /*onlyBlockPointers=*/true)) { moveAttrFromListToList(attr, state.getCurrentAttributes(), dest->getAttrs()); return; @@ -546,7 +538,7 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state, goto error; } } - error: +error: diagnoseBadTypeAttribute(state.getSema(), attr, type); } @@ -581,7 +573,7 @@ static void distributeObjCPointerTypeAttrFromDeclarator( goto done; } } - done: +done: // That might actually be the decl spec if we weren't blocked by // anything in the declarator. @@ -621,7 +613,7 @@ static void distributeFunctionTypeAttr(TypeProcessingState &state, // Try to push the attribute from the return type of a function to // the function itself. for (unsigned i = state.getCurrentChunkIndex(); i != 0; --i) { - DeclaratorChunk &chunk = declarator.getTypeObject(i-1); + DeclaratorChunk &chunk = declarator.getTypeObject(i - 1); switch (chunk.Kind) { case DeclaratorChunk::Function: moveAttrFromListToList(attr, state.getCurrentAttributes(), @@ -654,7 +646,8 @@ static bool distributeFunctionTypeAttrToInnermost( // Put it on the innermost function chunk, if there is one. for (unsigned i = 0, e = declarator.getNumTypeObjects(); i != e; ++i) { DeclaratorChunk &chunk = declarator.getTypeObject(i); - if (chunk.Kind != DeclaratorChunk::Function) continue; + if (chunk.Kind != DeclaratorChunk::Function) + continue; moveAttrFromListToList(attr, attrList, chunk.getAttrs()); return true; @@ -829,8 +822,8 @@ static void diagnoseAndRemoveTypeQualifiers(Sema &S, const DeclSpec &DS, if (!S.inTemplateInstantiation()) { if (TypeQuals & Qual.first) S.Diag(Qual.second, DiagID) - << DeclSpec::getSpecifierName(Qual.first) << TypeSoFar - << FixItHint::CreateRemoval(Qual.second); + << DeclSpec::getSpecifierName(Qual.first) << TypeSoFar + << FixItHint::CreateRemoval(Qual.second); } TypeQuals &= ~Qual.first; @@ -861,7 +854,8 @@ static bool checkOmittedBlockReturnType(Sema &S, Declarator &declarator, // Warn if we see type qualifiers for omitted return type on a block literal. const DeclSpec &DS = declarator.getDeclSpec(); unsigned TypeQuals = DS.getTypeQualifiers(); - diagnoseAndRemoveTypeQualifiers(S, DS, TypeQuals, Result, (unsigned)-1, + diagnoseAndRemoveTypeQualifiers( + S, DS, TypeQuals, Result, (unsigned)-1, diag::warn_block_literal_qualifiers_on_omitted_return_type); declarator.getMutableDeclSpec().ClearTypeQualifiers(); @@ -928,15 +922,15 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { Result = Context.WCharTy; else if (DS.getTypeSpecSign() == TypeSpecifierSign::Signed) { S.Diag(DS.getTypeSpecSignLoc(), diag::ext_wchar_t_sign_spec) - << DS.getSpecifierName(DS.getTypeSpecType(), - Context.getPrintingPolicy()); + << DS.getSpecifierName(DS.getTypeSpecType(), + Context.getPrintingPolicy()); Result = Context.getSignedWCharType(); } else { assert(DS.getTypeSpecSign() == TypeSpecifierSign::Unsigned && "Unknown TSS value"); S.Diag(DS.getTypeSpecSignLoc(), diag::ext_wchar_t_sign_spec) - << DS.getSpecifierName(DS.getTypeSpecType(), - Context.getPrintingPolicy()); + << DS.getSpecifierName(DS.getTypeSpecType(), + Context.getPrintingPolicy()); Result = Context.getUnsignedWCharType(); } break; @@ -1030,8 +1024,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { if (!S.getLangOpts().C99) { if (S.getLangOpts().CPlusPlus) S.Diag(DS.getTypeSpecWidthLoc(), - S.getLangOpts().CPlusPlus11 ? - diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong); + S.getLangOpts().CPlusPlus11 + ? diag::warn_cxx98_compat_longlong + : diag::ext_cxx11_longlong); else S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_c99_longlong); } @@ -1055,8 +1050,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { if (!S.getLangOpts().C99) { if (S.getLangOpts().CPlusPlus) S.Diag(DS.getTypeSpecWidthLoc(), - S.getLangOpts().CPlusPlus11 ? - diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong); + S.getLangOpts().CPlusPlus11 + ? diag::warn_cxx98_compat_longlong + : diag::ext_cxx11_longlong); else S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_c99_longlong); } @@ -1127,8 +1123,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { if (!S.Context.getTargetInfo().hasInt128Type() && !(S.getLangOpts().SYCLIsDevice || S.getLangOpts().CUDAIsDevice || (S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsTargetDevice))) - S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) - << "__int128"; + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "__int128"; if (DS.getTypeSpecSign() == TypeSpecifierSign::Unsigned) Result = Context.UnsignedInt128Ty; else @@ -1140,11 +1135,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { // ToDo: more precise diagnostics for CUDA. if (!S.Context.getTargetInfo().hasFloat16Type() && !S.getLangOpts().CUDA && !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsTargetDevice)) - S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) - << "_Float16"; + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "_Float16"; Result = Context.Float16Ty; break; - case DeclSpec::TST_half: Result = Context.HalfTy; break; + case DeclSpec::TST_half: + Result = Context.HalfTy; + break; case DeclSpec::TST_BFloat16: if (!S.Context.getTargetInfo().hasBFloat16Type() && !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsTargetDevice) && @@ -1152,7 +1148,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "__bf16"; Result = Context.BFloat16Ty; break; - case DeclSpec::TST_float: Result = Context.FloatTy; break; + case DeclSpec::TST_float: + Result = Context.FloatTy; + break; case DeclSpec::TST_double: if (DS.getTypeSpecWidth() == TypeSpecifierWidth::Long) Result = Context.LongDoubleTy; @@ -1165,7 +1163,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { << (S.getLangOpts().getOpenCLCompatibleVersion() == 300 ? "cl_khr_fp64 and __opencl_c_fp64" : "cl_khr_fp64"); - else if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp64", S.getLangOpts())) + else if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp64", + S.getLangOpts())) S.Diag(DS.getTypeSpecTypeLoc(), diag::ext_opencl_double_without_pragma); } break; @@ -1174,7 +1173,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { !S.getLangOpts().SYCLIsDevice && !S.getLangOpts().CUDAIsDevice && !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsTargetDevice)) S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) - << "__float128"; + << "__float128"; Result = Context.Float128Ty; break; case DeclSpec::TST_ibm128: @@ -1187,9 +1186,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { case DeclSpec::TST_bool: Result = Context.BoolTy; // _Bool or bool break; - case DeclSpec::TST_decimal32: // _Decimal32 - case DeclSpec::TST_decimal64: // _Decimal64 - case DeclSpec::TST_decimal128: // _Decimal128 + case DeclSpec::TST_decimal32: // _Decimal32 + case DeclSpec::TST_decimal64: // _Decimal64 + case DeclSpec::TST_decimal128: // _Decimal128 S.Diag(DS.getTypeSpecTypeLoc(), diag::err_decimal_unsupported); Result = Context.IntTy; declarator.setInvalidType(true); @@ -1220,8 +1219,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { Result = Context.getTypeDeclType(D); // In both C and C++, make an ElaboratedType. - ElaboratedTypeKeyword Keyword - = ElaboratedType::getKeywordForTypeSpec(DS.getTypeSpecType()); + ElaboratedTypeKeyword Keyword = + ElaboratedType::getKeywordForTypeSpec(DS.getTypeSpecType()); Result = S.getElaboratedType(Keyword, DS.getTypeSpecScope(), Result, DS.isTypeSpecOwned() ? D : nullptr); break; @@ -1336,7 +1335,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { } case DeclSpec::TST_auto_type: - Result = Context.getAutoType(QualType(), AutoTypeKeyword::GNUAutoType, false); + Result = + Context.getAutoType(QualType(), AutoTypeKeyword::GNUAutoType, false); break; case DeclSpec::TST_unknown_anytype: @@ -1440,7 +1440,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { VecKind = VectorKind::AltiVecPixel; else if (DS.isTypeAltiVecBool()) VecKind = VectorKind::AltiVecBool; - Result = Context.getVectorType(Result, 128/typeSize, VecKind); + Result = Context.getVectorType(Result, 128 / typeSize, VecKind); } // _Imaginary was a feature of C99 through C23 but was never supported in @@ -1536,16 +1536,15 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { // C90 6.5.3 constraints: "The same type qualifier shall not appear more // than once in the same specifier-list or qualifier-list, either directly // or via one or more typedefs." - if (!S.getLangOpts().C99 && !S.getLangOpts().CPlusPlus - && TypeQuals & Result.getCVRQualifiers()) { + if (!S.getLangOpts().C99 && !S.getLangOpts().CPlusPlus && + TypeQuals & Result.getCVRQualifiers()) { if (TypeQuals & DeclSpec::TQ_const && Result.isConstQualified()) { - S.Diag(DS.getConstSpecLoc(), diag::ext_duplicate_declspec) - << "const"; + S.Diag(DS.getConstSpecLoc(), diag::ext_duplicate_declspec) << "const"; } if (TypeQuals & DeclSpec::TQ_volatile && Result.isVolatileQualified()) { S.Diag(DS.getVolatileSpecLoc(), diag::ext_duplicate_declspec) - << "volatile"; + << "volatile"; } // C90 doesn't have restrict nor _Atomic, so it doesn't force us to @@ -1583,8 +1582,8 @@ static bool isDependentOrGNUAutoType(QualType T) { return AT && AT->isGNUAutoType(); } -QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc, - Qualifiers Qs, const DeclSpec *DS) { +QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, + const DeclSpec *DS) { if (T.isNull()) return QualType(); @@ -1677,9 +1676,7 @@ QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc, return BuildQualifiedType(T, Loc, Q, DS); } -QualType Sema::BuildParenType(QualType T) { - return Context.getParenType(T); -} +QualType Sema::BuildParenType(QualType T) { return Context.getParenType(T); } /// Given that we're building a pointer or reference to the given static QualType inferARCLifetimeForPointee(Sema &S, QualType type, @@ -1699,28 +1696,27 @@ static QualType inferARCLifetimeForPointee(Sema &S, QualType type, if (type.isConstQualified()) { implicitLifetime = Qualifiers::OCL_ExplicitNone; - // Otherwise, check whether the static type does not require - // retaining. This currently only triggers for Class (possibly - // protocol-qualifed, and arrays thereof). + // Otherwise, check whether the static type does not require + // retaining. This currently only triggers for Class (possibly + // protocol-qualifed, and arrays thereof). } else if (type->isObjCARCImplicitlyUnretainedType()) { implicitLifetime = Qualifiers::OCL_ExplicitNone; - // If we are in an unevaluated context, like sizeof, skip adding a - // qualification. + // If we are in an unevaluated context, like sizeof, skip adding a + // qualification. } else if (S.isUnevaluatedContext()) { return type; - // If that failed, give an error and recover using __strong. __strong - // is the option most likely to prevent spurious second-order diagnostics, - // like when binding a reference to a field. + // If that failed, give an error and recover using __strong. __strong + // is the option most likely to prevent spurious second-order diagnostics, + // like when binding a reference to a field. } else { // These types can show up in private ivars in system headers, so // we need this to not be an error in those cases. Instead we // want to delay. if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { - S.DelayedDiagnostics.add( - sema::DelayedDiagnostic::makeForbiddenType(loc, - diag::err_arc_indirect_no_ownership, type, isReference)); + S.DelayedDiagnostics.add(sema::DelayedDiagnostic::makeForbiddenType( + loc, diag::err_arc_indirect_no_ownership, type, isReference)); } else { S.Diag(loc, diag::err_arc_indirect_no_ownership) << type << isReference; } @@ -1733,7 +1729,8 @@ static QualType inferARCLifetimeForPointee(Sema &S, QualType type, return S.Context.getQualifiedType(type, qs); } -static std::string getFunctionQualifiersAsString(const FunctionProtoType *FnTy){ +static std::string +getFunctionQualifiersAsString(const FunctionProtoType *FnTy) { std::string Quals = FnTy->getMethodQuals().getAsString(); switch (FnTy->getRefQualifier()) { @@ -1781,8 +1778,8 @@ static bool checkQualifiedFunction(Sema &S, QualType T, SourceLocation Loc, return false; S.Diag(Loc, diag::err_compound_qualified_function_type) - << QFK << isa(T.IgnoreParens()) << T - << getFunctionQualifiersAsString(FPT); + << QFK << isa(T.IgnoreParens()) << T + << getFunctionQualifiersAsString(FPT); return true; } @@ -1800,19 +1797,18 @@ bool Sema::CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc) { // Helper to deduce addr space of a pointee type in OpenCL mode. static QualType deduceOpenCLPointeeAddrSpace(Sema &S, QualType PointeeType) { if (!PointeeType->isUndeducedAutoType() && !PointeeType->isDependentType() && - !PointeeType->isSamplerT() && - !PointeeType.hasAddressSpace()) + !PointeeType->isSamplerT() && !PointeeType.hasAddressSpace()) PointeeType = S.getASTContext().getAddrSpaceQualType( PointeeType, S.getASTContext().getDefaultOpenCLPointeeAddrSpace()); return PointeeType; } -QualType Sema::BuildPointerType(QualType T, - SourceLocation Loc, DeclarationName Entity) { +QualType Sema::BuildPointerType(QualType T, SourceLocation Loc, + DeclarationName Entity) { if (T->isReferenceType()) { // C++ 8.3.2p4: There shall be no ... pointers to references ... Diag(Loc, diag::err_illegal_decl_pointer_to_reference) - << getPrintableNameForEntity(Entity) << T; + << getPrintableNameForEntity(Entity) << T; return QualType(); } @@ -1860,8 +1856,7 @@ QualType Sema::BuildPointerType(QualType T, } QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue, - SourceLocation Loc, - DeclarationName Entity) { + SourceLocation Loc, DeclarationName Entity) { assert(Context.getCanonicalType(T) != Context.OverloadTy && "Unresolved overloaded function type"); @@ -2069,7 +2064,7 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM, // Note: function types are handled in the common path with C. if (T->isReferenceType()) { Diag(Loc, diag::err_illegal_decl_array_of_references) - << getPrintableNameForEntity(Entity) << T; + << getPrintableNameForEntity(Entity) << T; return QualType(); } @@ -2114,7 +2109,7 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM, if (T->isFunctionType()) { Diag(Loc, diag::err_illegal_decl_array_of_functions) - << getPrintableNameForEntity(Entity) << T; + << getPrintableNameForEntity(Entity) << T; return QualType(); } @@ -2134,7 +2129,8 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM, // Do placeholder conversions on the array size expression. if (ArraySize && ArraySize->hasPlaceholderType()) { ExprResult Result = CheckPlaceholderExpr(ArraySize); - if (Result.isInvalid()) return QualType(); + if (Result.isInvalid()) + return QualType(); ArraySize = Result.get(); } @@ -2149,8 +2145,8 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM, // C99 6.7.5.2p1: The size expression shall have integer type. // C++11 allows contextual conversions to such types. - if (!getLangOpts().CPlusPlus11 && - ArraySize && !ArraySize->isTypeDependent() && + if (!getLangOpts().CPlusPlus11 && ArraySize && + !ArraySize->isTypeDependent() && !ArraySize->getType()->isIntegralOrUnscopedEnumerationType()) { Diag(ArraySize->getBeginLoc(), diag::err_array_size_non_int) << ArraySize->getType() << ArraySize->getSourceRange(); @@ -2423,8 +2419,8 @@ QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize, ArraySize->getIntegerConstantExpr(Context); if (!vecSize) { Diag(AttrLoc, diag::err_attribute_argument_type) - << "ext_vector_type" << AANT_ArgumentIntegerConstant - << ArraySize->getSourceRange(); + << "ext_vector_type" << AANT_ArgumentIntegerConstant + << ArraySize->getSourceRange(); return QualType(); } @@ -2528,15 +2524,15 @@ QualType Sema::BuildMatrixType(QualType ElementTy, Expr *NumRows, Expr *NumCols, bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) { if (T->isArrayType() || T->isFunctionType()) { Diag(Loc, diag::err_func_returning_array_function) - << T->isFunctionType() << T; + << T->isFunctionType() << T; return true; } // Functions cannot return half FP. if (T->isHalfType() && !getLangOpts().NativeHalfArgsAndReturns && !Context.getTargetInfo().allowHalfArgsAndReturns()) { - Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) << 1 << - FixItHint::CreateInsertion(Loc, "*"); + Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) + << 1 << FixItHint::CreateInsertion(Loc, "*"); return true; } @@ -2551,7 +2547,7 @@ bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) { if (T.hasNonTrivialToPrimitiveDestructCUnion() || T.hasNonTrivialToPrimitiveCopyCUnion()) checkNonTrivialCUnion(T, Loc, NTCUC_FunctionReturn, - NTCUK_Destruct|NTCUK_Copy); + NTCUK_Destruct | NTCUK_Copy); // C++2a [dcl.fct]p12: // A volatile-qualified return type is deprecated @@ -2566,9 +2562,10 @@ bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) { /// Check the extended parameter information. Most of the necessary /// checking should occur when applying the parameter attribute; the /// only other checks required are positional restrictions. -static void checkExtParameterInfos(Sema &S, ArrayRef paramTypes, - const FunctionProtoType::ExtProtoInfo &EPI, - llvm::function_ref getParamLoc) { +static void checkExtParameterInfos( + Sema &S, ArrayRef paramTypes, + const FunctionProtoType::ExtProtoInfo &EPI, + llvm::function_ref getParamLoc) { assert(EPI.ExtParameterInfos && "shouldn't get here without param infos"); bool emittedError = false; @@ -2587,7 +2584,7 @@ static void checkExtParameterInfos(Sema &S, ArrayRef paramTypes, emittedError = true; }; for (size_t paramIndex = 0, numParams = paramTypes.size(); - paramIndex != numParams; ++paramIndex) { + paramIndex != numParams; ++paramIndex) { switch (EPI.ExtParameterInfos[paramIndex].getABI()) { // Nothing interesting to check for orindary-ABI parameters. case ParameterABI::Ordinary: @@ -2599,9 +2596,8 @@ static void checkExtParameterInfos(Sema &S, ArrayRef paramTypes, // arguments. case ParameterABI::SwiftIndirectResult: checkCompatible(paramIndex, RequiredCC::SwiftOrSwiftAsync); - if (paramIndex != 0 && - EPI.ExtParameterInfos[paramIndex - 1].getABI() - != ParameterABI::SwiftIndirectResult) { + if (paramIndex != 0 && EPI.ExtParameterInfos[paramIndex - 1].getABI() != + ParameterABI::SwiftIndirectResult) { S.Diag(getParamLoc(paramIndex), diag::err_swift_indirect_result_not_first); } @@ -2618,9 +2614,8 @@ static void checkExtParameterInfos(Sema &S, ArrayRef paramTypes, // swift_error parameters must be preceded by a swift_context parameter. case ParameterABI::SwiftErrorResult: checkCompatible(paramIndex, RequiredCC::OnlySwift); - if (paramIndex == 0 || - EPI.ExtParameterInfos[paramIndex - 1].getABI() != - ParameterABI::SwiftContext) { + if (paramIndex == 0 || EPI.ExtParameterInfos[paramIndex - 1].getABI() != + ParameterABI::SwiftContext) { S.Diag(getParamLoc(paramIndex), diag::err_swift_error_result_not_after_swift_context); } @@ -2644,11 +2639,12 @@ QualType Sema::BuildFunctionType(QualType T, if (ParamType->isVoidType()) { Diag(Loc, diag::err_param_with_void_type); Invalid = true; - } else if (ParamType->isHalfType() && !getLangOpts().NativeHalfArgsAndReturns && + } else if (ParamType->isHalfType() && + !getLangOpts().NativeHalfArgsAndReturns && !Context.getTargetInfo().allowHalfArgsAndReturns()) { // Disallow half FP arguments. - Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) << 0 << - FixItHint::CreateInsertion(Loc, "*"); + Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) + << 0 << FixItHint::CreateInsertion(Loc, "*"); Invalid = true; } else if (ParamType->isWebAssemblyTableType()) { Diag(Loc, diag::err_wasm_table_as_function_parameter); @@ -2693,13 +2689,13 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, // with reference type, or "cv void." if (T->isReferenceType()) { Diag(Loc, diag::err_illegal_decl_mempointer_to_reference) - << getPrintableNameForEntity(Entity) << T; + << getPrintableNameForEntity(Entity) << T; return QualType(); } if (T->isVoidType()) { Diag(Loc, diag::err_illegal_decl_mempointer_to_void) - << getPrintableNameForEntity(Entity); + << getPrintableNameForEntity(Entity); return QualType(); } @@ -2731,8 +2727,7 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, return Context.getMemberPointerType(T, Class.getTypePtr()); } -QualType Sema::BuildBlockPointerType(QualType T, - SourceLocation Loc, +QualType Sema::BuildBlockPointerType(QualType T, SourceLocation Loc, DeclarationName Entity) { if (!T->isFunctionType()) { Diag(Loc, diag::err_nonfunction_block_type); @@ -2751,7 +2746,8 @@ QualType Sema::BuildBlockPointerType(QualType T, QualType Sema::GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo) { QualType QT = Ty.get(); if (QT.isNull()) { - if (TInfo) *TInfo = nullptr; + if (TInfo) + *TInfo = nullptr; return QualType(); } @@ -2761,13 +2757,15 @@ QualType Sema::GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo) { DI = LIT->getTypeSourceInfo(); } - if (TInfo) *TInfo = DI; + if (TInfo) + *TInfo = DI; return QT; } -static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state, - Qualifiers::ObjCLifetime ownership, - unsigned chunkIndex); +static void +transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state, + Qualifiers::ObjCLifetime ownership, + unsigned chunkIndex); /// Given that this is the declaration of a parameter under ARC, /// attempt to infer attributes and such for pointer-to-whatever @@ -2805,7 +2803,8 @@ static void inferARCWriteback(TypeProcessingState &state, // If we have a pointer to block pointer, that's an acceptable // indirect reference; anything else is not an application of // the rules. - if (numPointers != 1) return; + if (numPointers != 1) + return; numPointers++; outermostPointerIndex = chunkIndex; isBlockPointer = true; @@ -2820,17 +2819,19 @@ static void inferARCWriteback(TypeProcessingState &state, return; } } - done: +done: // If we have *one* pointer, then we want to throw the qualifier on // the declaration-specifiers, which means that it needs to be a // retainable object type. if (numPointers == 1) { // If it's not a retainable object type, the rule doesn't apply. - if (!declSpecType->isObjCRetainableType()) return; + if (!declSpecType->isObjCRetainableType()) + return; // If it already has lifetime, don't do anything. - if (declSpecType.getObjCLifetime()) return; + if (declSpecType.getObjCLifetime()) + return; // Otherwise, modify the type in-place. Qualifiers qs; @@ -2841,8 +2842,8 @@ static void inferARCWriteback(TypeProcessingState &state, qs.addObjCLifetime(Qualifiers::OCL_Autoreleasing); declSpecType = S.Context.getQualifiedType(declSpecType, qs); - // If we have *two* pointers, then we want to throw the qualifier on - // the outermost pointer. + // If we have *two* pointers, then we want to throw the qualifier on + // the outermost pointer. } else if (numPointers == 2) { // If we don't have a block pointer, we need to check whether the // declaration-specifiers gave us something that will turn into a @@ -2862,8 +2863,9 @@ static void inferARCWriteback(TypeProcessingState &state, transferARCOwnershipToDeclaratorChunk(state, Qualifiers::OCL_Autoreleasing, outermostPointerIndex); - // Any other number of pointers/references does not trigger the rule. - } else return; + // Any other number of pointers/references does not trigger the rule. + } else + return; // TODO: mark whether we did this inference? } @@ -2883,12 +2885,11 @@ void Sema::diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, unsigned Mask; SourceLocation Loc; } const QualKinds[5] = { - { "const", DeclSpec::TQ_const, ConstQualLoc }, - { "volatile", DeclSpec::TQ_volatile, VolatileQualLoc }, - { "restrict", DeclSpec::TQ_restrict, RestrictQualLoc }, - { "__unaligned", DeclSpec::TQ_unaligned, UnalignedQualLoc }, - { "_Atomic", DeclSpec::TQ_atomic, AtomicQualLoc } - }; + {"const", DeclSpec::TQ_const, ConstQualLoc}, + {"volatile", DeclSpec::TQ_volatile, VolatileQualLoc}, + {"restrict", DeclSpec::TQ_restrict, RestrictQualLoc}, + {"__unaligned", DeclSpec::TQ_unaligned, UnalignedQualLoc}, + {"_Atomic", DeclSpec::TQ_atomic, AtomicQualLoc}}; SmallString<32> QualStr; unsigned NumQuals = 0; @@ -2898,7 +2899,8 @@ void Sema::diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, // Build a string naming the redundant qualifiers. for (auto &E : QualKinds) { if (Quals & E.Mask) { - if (!QualStr.empty()) QualStr += ' '; + if (!QualStr.empty()) + QualStr += ' '; QualStr += E.Name; // If we have a location for the qualifier, offer a fixit. @@ -2915,7 +2917,8 @@ void Sema::diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, } Diag(Loc.isInvalid() ? FallbackLoc : Loc, DiagID) - << QualStr << NumQuals << FixIts[0] << FixIts[1] << FixIts[2] << FixIts[3]; + << QualStr << NumQuals << FixIts[0] << FixIts[1] << FixIts[2] + << FixIts[3]; } // Diagnose pointless type qualifiers on the return type of a function. @@ -2941,15 +2944,10 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy, case DeclaratorChunk::Pointer: { DeclaratorChunk::PointerTypeInfo &PTI = OuterChunk.Ptr; - S.diagnoseIgnoredQualifiers( - diag::warn_qual_return_type, - PTI.TypeQuals, - SourceLocation(), - PTI.ConstQualLoc, - PTI.VolatileQualLoc, - PTI.RestrictQualLoc, - PTI.AtomicQualLoc, - PTI.UnalignedQualLoc); + S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type, PTI.TypeQuals, + SourceLocation(), PTI.ConstQualLoc, + PTI.VolatileQualLoc, PTI.RestrictQualLoc, + PTI.AtomicQualLoc, PTI.UnalignedQualLoc); return; } @@ -2979,14 +2977,12 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy, // Just parens all the way out to the decl specifiers. Diagnose any qualifiers // which are present there. - S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type, - D.getDeclSpec().getTypeQualifiers(), - D.getIdentifierLoc(), - D.getDeclSpec().getConstSpecLoc(), - D.getDeclSpec().getVolatileSpecLoc(), - D.getDeclSpec().getRestrictSpecLoc(), - D.getDeclSpec().getAtomicSpecLoc(), - D.getDeclSpec().getUnalignedSpecLoc()); + S.diagnoseIgnoredQualifiers( + diag::warn_qual_return_type, D.getDeclSpec().getTypeQualifiers(), + D.getIdentifierLoc(), D.getDeclSpec().getConstSpecLoc(), + D.getDeclSpec().getVolatileSpecLoc(), + D.getDeclSpec().getRestrictSpecLoc(), D.getDeclSpec().getAtomicSpecLoc(), + D.getDeclSpec().getUnalignedSpecLoc()); } static std::pair @@ -3006,15 +3002,14 @@ InventTemplateParameter(TypeProcessingState &state, QualType T, // Create the TemplateTypeParmDecl here to retrieve the corresponding // template parameter type. Template parameters are temporarily added // to the TU until the associated TemplateDecl is created. - TemplateTypeParmDecl *InventedTemplateParam = - TemplateTypeParmDecl::Create( - S.Context, S.Context.getTranslationUnitDecl(), - /*KeyLoc=*/D.getDeclSpec().getTypeSpecTypeLoc(), - /*NameLoc=*/D.getIdentifierLoc(), - TemplateParameterDepth, AutoParameterPosition, - S.InventAbbreviatedTemplateParameterTypeName( - D.getIdentifier(), AutoParameterPosition), false, - IsParameterPack, /*HasTypeConstraint=*/Auto->isConstrained()); + TemplateTypeParmDecl *InventedTemplateParam = TemplateTypeParmDecl::Create( + S.Context, S.Context.getTranslationUnitDecl(), + /*KeyLoc=*/D.getDeclSpec().getTypeSpecTypeLoc(), + /*NameLoc=*/D.getIdentifierLoc(), TemplateParameterDepth, + AutoParameterPosition, + S.InventAbbreviatedTemplateParameterTypeName(D.getIdentifier(), + AutoParameterPosition), + false, IsParameterPack, /*HasTypeConstraint=*/Auto->isConstrained()); InventedTemplateParam->setImplicit(); Info.TemplateParams.push_back(InventedTemplateParam); @@ -3024,7 +3019,8 @@ InventTemplateParameter(TypeProcessingState &state, QualType T, // The 'auto' appears in a trailing return type we've already built; // extract its type constraints to attach to the template parameter. AutoTypeLoc AutoLoc = TrailingTSI->getTypeLoc().getContainedAutoTypeLoc(); - TemplateArgumentListInfo TAL(AutoLoc.getLAngleLoc(), AutoLoc.getRAngleLoc()); + TemplateArgumentListInfo TAL(AutoLoc.getLAngleLoc(), + AutoLoc.getRAngleLoc()); bool Invalid = false; for (unsigned Idx = 0; Idx < AutoLoc.getNumArgs(); ++Idx) { if (D.getEllipsisLoc().isInvalid() && !Invalid && @@ -3098,8 +3094,8 @@ InventTemplateParameter(TypeProcessingState &state, QualType T, } static TypeSourceInfo * -GetTypeSourceInfoForDeclarator(TypeProcessingState &State, - QualType T, TypeSourceInfo *ReturnTypeInfo); +GetTypeSourceInfoForDeclarator(TypeProcessingState &State, QualType T, + TypeSourceInfo *ReturnTypeInfo); static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, TypeSourceInfo *&ReturnTypeInfo) { @@ -3344,9 +3340,15 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, unsigned Kind; if (Auto) { switch (Auto->getKeyword()) { - case AutoTypeKeyword::Auto: Kind = 0; break; - case AutoTypeKeyword::DecltypeAuto: Kind = 1; break; - case AutoTypeKeyword::GNUAutoType: Kind = 2; break; + case AutoTypeKeyword::Auto: + Kind = 0; + break; + case AutoTypeKeyword::DecltypeAuto: + Kind = 1; + break; + case AutoTypeKeyword::GNUAutoType: + Kind = 2; + break; } } else { assert(isa(Deduced) && @@ -3358,8 +3360,8 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, TemplateName TN = DTST ? DTST->getTemplateName() : TemplateName(); SemaRef.Diag(AutoRange.getBegin(), diag::err_auto_not_allowed) - << Kind << Error << (int)SemaRef.getTemplateNameKindForDiagnostics(TN) - << QualType(Deduced, 0) << AutoRange; + << Kind << Error << (int)SemaRef.getTemplateNameKindForDiagnostics(TN) + << QualType(Deduced, 0) << AutoRange; if (auto *TD = TN.getAsTemplateDecl()) SemaRef.NoteTemplateLocation(*TD); @@ -3378,8 +3380,8 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, } } - if (SemaRef.getLangOpts().CPlusPlus && - OwnedTagDecl && OwnedTagDecl->isCompleteDefinition()) { + if (SemaRef.getLangOpts().CPlusPlus && OwnedTagDecl && + OwnedTagDecl->isCompleteDefinition()) { // Check the contexts where C++ forbids the declaration of a new class // or enumeration in a type-specifier-seq. unsigned DiagID = 0; @@ -3500,8 +3502,8 @@ static void warnAboutAmbiguousFunction(Sema &S, Declarator &D, Sema::LookupOrdinaryName); if (S.LookupName(Result, S.getCurScope())) S.Diag(D.getCommaLoc(), diag::note_empty_parens_function_call) - << FixItHint::CreateReplacement(D.getCommaLoc(), ";") - << D.getIdentifier(); + << FixItHint::CreateReplacement(D.getCommaLoc(), ";") + << D.getIdentifier(); Result.suppressDiagnostics(); } } @@ -3516,8 +3518,8 @@ static void warnAboutAmbiguousFunction(Sema &S, Declarator &D, // FIXME: Maybe we should suggest adding braces instead of parens // in C++11 for classes that don't have an initializer_list constructor. S.Diag(B, diag::note_additional_parens_for_variable_declaration) - << FixItHint::CreateInsertion(B, "(") - << FixItHint::CreateInsertion(E, ")"); + << FixItHint::CreateInsertion(B, "(") + << FixItHint::CreateInsertion(E, ")"); } else { // For a declaration without parameters, eg. "T var();", suggest replacing // the parens with an initializer to turn the declaration into a variable @@ -3531,7 +3533,7 @@ static void warnAboutAmbiguousFunction(Sema &S, Declarator &D, if (RD && RD->hasDefinition() && (RD->isEmpty() || RD->hasUserProvidedDefaultConstructor())) S.Diag(DeclType.Loc, diag::note_empty_parens_default_ctor) - << FixItHint::CreateRemoval(ParenRange); + << FixItHint::CreateRemoval(ParenRange); else { std::string Init = S.getFixItZeroInitializerForType(RT, ParenRange.getBegin()); @@ -3539,7 +3541,7 @@ static void warnAboutAmbiguousFunction(Sema &S, Declarator &D, Init = "{}"; if (!Init.empty()) S.Diag(DeclType.Loc, diag::note_empty_parens_zero_initialize) - << FixItHint::CreateReplacement(ParenRange, Init); + << FixItHint::CreateReplacement(ParenRange, Init); } } } @@ -3673,7 +3675,7 @@ static CallingConv getCCForDeclaratorChunk( // Check for an explicit CC attribute. for (const ParsedAttr &AL : AttrList) { switch (AL.getKind()) { - CALLING_CONV_ATTRS_CASELIST : { + CALLING_CONV_ATTRS_CASELIST: { // Ignore attributes that don't validate or can't apply to the // function type. We'll diagnose the failure to apply them in // handleFunctionTypeAttr. @@ -3762,14 +3764,14 @@ static CallingConv getCCForDeclaratorChunk( } namespace { - /// A simple notion of pointer kinds, which matches up with the various - /// pointer declarators. - enum class SimplePointerKind { - Pointer, - BlockPointer, - MemberPointer, - Array, - }; +/// A simple notion of pointer kinds, which matches up with the various +/// pointer declarators. +enum class SimplePointerKind { + Pointer, + BlockPointer, + MemberPointer, + Array, +}; } // end anonymous namespace IdentifierInfo *Sema::getNullabilityKeyword(NullabilityKind nullability) { @@ -3812,33 +3814,33 @@ static bool hasNullabilityAttr(const ParsedAttributesView &attrs) { } namespace { - /// Describes the kind of a pointer a declarator describes. - enum class PointerDeclaratorKind { - // Not a pointer. - NonPointer, - // Single-level pointer. - SingleLevelPointer, - // Multi-level pointer (of any pointer kind). - MultiLevelPointer, - // CFFooRef* - MaybePointerToCFRef, - // CFErrorRef* - CFErrorRefPointer, - // NSError** - NSErrorPointerPointer, - }; +/// Describes the kind of a pointer a declarator describes. +enum class PointerDeclaratorKind { + // Not a pointer. + NonPointer, + // Single-level pointer. + SingleLevelPointer, + // Multi-level pointer (of any pointer kind). + MultiLevelPointer, + // CFFooRef* + MaybePointerToCFRef, + // CFErrorRef* + CFErrorRefPointer, + // NSError** + NSErrorPointerPointer, +}; - /// Describes a declarator chunk wrapping a pointer that marks inference as - /// unexpected. - // These values must be kept in sync with diagnostics. - enum class PointerWrappingDeclaratorKind { - /// Pointer is top-level. - None = -1, - /// Pointer is an array element. - Array = 0, - /// Pointer is the referent type of a C++ reference. - Reference = 1 - }; +/// Describes a declarator chunk wrapping a pointer that marks inference as +/// unexpected. +// These values must be kept in sync with diagnostics. +enum class PointerWrappingDeclaratorKind { + /// Pointer is top-level. + None = -1, + /// Pointer is an array element. + Array = 0, + /// Pointer is the referent type of a C++ reference. + Reference = 1 +}; } // end anonymous namespace /// Classify the given declarator, whose type-specified is \c type, based on @@ -4060,7 +4062,7 @@ static void emitNullabilityConsistencyWarning(Sema &S, S.Diag(PointerLoc, diag::warn_nullability_missing_array); } else { S.Diag(PointerLoc, diag::warn_nullability_missing) - << static_cast(PointerKind); + << static_cast(PointerKind); } auto FixItLoc = PointerEndLoc.isValid() ? PointerEndLoc : PointerLoc; @@ -4183,7 +4185,7 @@ static bool IsNoDerefableChunk(const DeclaratorChunk &Chunk) { Chunk.Kind == DeclaratorChunk::Array); } -template +template static AttrT *createSimpleAttr(ASTContext &Ctx, ParsedAttr &AL) { AL.setUsedAsTypeAttr(); return ::new (Ctx) AttrT(Ctx, AL); @@ -4220,8 +4222,7 @@ static bool DiagnoseMultipleAddrSpaceAttributes(Sema &S, LangAS ASOld, return true; } // Emit a warning if they are identical; it's likely unintended. - S.Diag(AttrLoc, - diag::warn_attribute_address_multiple_identical_qualifiers); + S.Diag(AttrLoc, diag::warn_attribute_address_multiple_identical_qualifiers); } return false; } @@ -4262,7 +4263,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, D.getContext() == DeclaratorContext::AliasTemplate; // Does T refer to a function type with a cv-qualifier or a ref-qualifier? - bool IsQualifiedFunction = T->isFunctionProtoType() && + bool IsQualifiedFunction = + T->isFunctionProtoType() && (!T->castAs()->getMethodQuals().empty() || T->castAs()->getRefQualifier() != RQ_None); @@ -4518,8 +4520,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // Returns true if _Nonnull was inferred. auto inferPointerNullability = [&](SimplePointerKind pointerKind, SourceLocation pointerLoc, - SourceLocation pointerEndLoc, - ParsedAttributesView &attrs, AttributePool &Pool) -> ParsedAttr * { + SourceLocation pointerEndLoc, ParsedAttributesView &attrs, + AttributePool &Pool) -> ParsedAttr * { // We've seen a pointer. if (NumPointersRemaining > 0) --NumPointersRemaining; @@ -4542,13 +4544,14 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, attrs.addAtEnd(nullabilityAttr); if (inferNullabilityCS) { - state.getDeclarator().getMutableDeclSpec().getObjCQualifiers() - ->setObjCDeclQualifier(ObjCDeclSpec::DQ_CSNullability); + state.getDeclarator() + .getMutableDeclSpec() + .getObjCQualifiers() + ->setObjCDeclQualifier(ObjCDeclSpec::DQ_CSNullability); } - if (pointerLoc.isValid() && - complainAboutInferringWithinChunk != - PointerWrappingDeclaratorKind::None) { + if (pointerLoc.isValid() && complainAboutInferringWithinChunk != + PointerWrappingDeclaratorKind::None) { auto Diag = S.Diag(pointerLoc, diag::warn_nullability_inferred_on_nested_type); Diag << static_cast(complainAboutInferringWithinChunk); @@ -4712,7 +4715,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // Build the type anyway. } DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr; - Expr *ArraySize = static_cast(ATI.NumElts); + Expr *ArraySize = static_cast(ATI.NumElts); ArraySizeModifier ASM; // Microsoft property fields can have multiple sizeless array chunks @@ -4852,8 +4855,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // trailing-return-type is only required if we're declaring a function, // and not, for instance, a pointer to a function. - if (D.getDeclSpec().hasAutoTypeSpec() && - !FTI.hasTrailingReturnType() && chunkIndex == 0) { + if (D.getDeclSpec().hasAutoTypeSpec() && !FTI.hasTrailingReturnType() && + chunkIndex == 0) { if (!S.getLangOpts().CPlusPlus14) { S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(), D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto @@ -4951,7 +4954,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, } else if (!S.getLangOpts().NativeHalfArgsAndReturns && !S.Context.getTargetInfo().allowHalfArgsAndReturns()) { S.Diag(D.getIdentifierLoc(), - diag::err_parameters_retval_cannot_have_fp16_type) << 1; + diag::err_parameters_retval_cannot_have_fp16_type) + << 1; D.setInvalidType(true); } } @@ -4992,8 +4996,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, FixitLoc = S.getLocForEndOfToken(D.getDeclSpec().getEndLoc()); } S.Diag(DiagLoc, diag::err_object_cannot_be_passed_returned_by_value) - << 0 << T - << FixItHint::CreateInsertion(FixitLoc, "*"); + << 0 << T << FixItHint::CreateInsertion(FixitLoc, "*"); T = Context.getObjCObjectPointerType(T); if (TInfo) { @@ -5062,7 +5065,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, S.SourceMgr.getImmediateExpansionRange(AttrLoc).getBegin(); S.Diag(AttrLoc, diag::warn_arc_lifetime_result_type) - << T.getQualifiers().getObjCLifetime(); + << T.getQualifiers().getObjCLifetime(); } } @@ -5071,7 +5074,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // Types shall not be defined in return or parameter types. TagDecl *Tag = cast(D.getDeclSpec().getRepAsDecl()); S.Diag(Tag->getLocation(), diag::err_type_defined_in_result_type) - << Context.getTypeDeclType(Tag); + << Context.getTypeDeclType(Tag); } // Exception specs are not allowed in typedefs. Complain, but add it @@ -5136,17 +5139,17 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, EPI.TypeQuals.addCVRUQualifiers( FTI.MethodQualifiers ? FTI.MethodQualifiers->getTypeQualifiers() : 0); - EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None - : FTI.RefQualifierIsLValueRef? RQ_LValue - : RQ_RValue; + EPI.RefQualifier = !FTI.hasRefQualifier() ? RQ_None + : FTI.RefQualifierIsLValueRef ? RQ_LValue + : RQ_RValue; // Otherwise, we have a function with a parameter list that is // potentially variadic. SmallVector ParamTys; ParamTys.reserve(FTI.NumParams); - SmallVector - ExtParameterInfos(FTI.NumParams); + SmallVector ExtParameterInfos( + FTI.NumParams); bool HasAnyInterestingExtParameterInfos = false; for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) { @@ -5200,7 +5203,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, } else if (!S.getLangOpts().NativeHalfArgsAndReturns && !S.Context.getTargetInfo().allowHalfArgsAndReturns()) { S.Diag(Param->getLocation(), - diag::err_parameters_retval_cannot_have_fp16_type) << 0; + diag::err_parameters_retval_cannot_have_fp16_type) + << 0; D.setInvalidType(); } } else if (!FTI.hasPrototype) { @@ -5226,8 +5230,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, } if (auto attr = Param->getAttr()) { - ExtParameterInfos[i] = - ExtParameterInfos[i].withABI(attr->getABI()); + ExtParameterInfos[i] = ExtParameterInfos[i].withABI(attr->getABI()); HasAnyInterestingExtParameterInfos = true; } @@ -5246,8 +5249,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, if (HasAnyInterestingExtParameterInfos) { EPI.ExtParameterInfos = ExtParameterInfos.data(); - checkExtParameterInfos(S, ParamTys, EPI, - [&](unsigned i) { return FTI.Params[i].Param->getLocation(); }); + checkExtParameterInfos(S, ParamTys, EPI, [&](unsigned i) { + return FTI.Params[i].Param->getLocation(); + }); } SmallVector Exceptions; @@ -5269,13 +5273,10 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, NoexceptExpr = FTI.NoexceptExpr; } - S.checkExceptionSpecification(D.isFunctionDeclarationContext(), - FTI.getExceptionSpecType(), - DynamicExceptions, - DynamicExceptionRanges, - NoexceptExpr, - Exceptions, - EPI.ExceptionSpec); + S.checkExceptionSpecification( + D.isFunctionDeclarationContext(), FTI.getExceptionSpecType(), + DynamicExceptions, DynamicExceptionRanges, NoexceptExpr, Exceptions, + EPI.ExceptionSpec); // FIXME: Set address space from attrs for C++ mode here. // OpenCLCPlusPlus: A class member function has an address space. @@ -5359,9 +5360,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, } } else { S.Diag(DeclType.Mem.Scope().getBeginLoc(), - diag::err_illegal_decl_mempointer_in_nonclass) - << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name") - << DeclType.Mem.Scope().getRange(); + diag::err_illegal_decl_mempointer_in_nonclass) + << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name") + << DeclType.Mem.Scope().getRange(); D.setInvalidType(true); } @@ -5548,9 +5549,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, } S.Diag(Loc, diag::err_invalid_qualified_function_type) - << Kind << D.isFunctionDeclarator() << T - << getFunctionQualifiersAsString(FnTy) - << FixItHint::CreateRemoval(RemovalRange); + << Kind << D.isFunctionDeclarator() << T + << getFunctionQualifiersAsString(FnTy) + << FixItHint::CreateRemoval(RemovalRange); // Strip the cv-qualifiers and ref-qualifiers from the type. FunctionProtoType::ExtProtoInfo EPI = FnTy->getExtProtoInfo(); @@ -5618,8 +5619,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, if (!T->containsUnexpandedParameterPack() && (!LangOpts.CPlusPlus20 || !T->getContainedAutoType())) { S.Diag(D.getEllipsisLoc(), - diag::err_function_parameter_pack_without_parameter_packs) - << T << D.getSourceRange(); + diag::err_function_parameter_pack_without_parameter_packs) + << T << D.getSourceRange(); D.setEllipsisLoc(SourceLocation()); } else { T = Context.getPackExpansionType(T, std::nullopt, @@ -5639,9 +5640,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, T = Context.getPackExpansionType(T, std::nullopt); else S.Diag(D.getEllipsisLoc(), - LangOpts.CPlusPlus11 - ? diag::warn_cxx98_compat_variadic_templates - : diag::ext_variadic_templates); + LangOpts.CPlusPlus11 ? diag::warn_cxx98_compat_variadic_templates + : diag::ext_variadic_templates); break; case DeclaratorContext::File: @@ -5697,8 +5697,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D) { return GetFullTypeForDeclarator(state, T, ReturnTypeInfo); } -static void transferARCOwnershipToDeclSpec(Sema &S, - QualType &declSpecTy, +static void transferARCOwnershipToDeclSpec(Sema &S, QualType &declSpecTy, Qualifiers::ObjCLifetime ownership) { if (declSpecTy->isObjCRetainableType() && declSpecTy.getObjCLifetime() == Qualifiers::OCL_None) { @@ -5708,9 +5707,10 @@ static void transferARCOwnershipToDeclSpec(Sema &S, } } -static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state, - Qualifiers::ObjCLifetime ownership, - unsigned chunkIndex) { +static void +transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state, + Qualifiers::ObjCLifetime ownership, + unsigned chunkIndex) { Sema &S = state.getSema(); Declarator &D = state.getDeclarator(); @@ -5721,11 +5721,20 @@ static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state, const char *attrStr = nullptr; switch (ownership) { - case Qualifiers::OCL_None: llvm_unreachable("no ownership!"); - case Qualifiers::OCL_ExplicitNone: attrStr = "none"; break; - case Qualifiers::OCL_Strong: attrStr = "strong"; break; - case Qualifiers::OCL_Weak: attrStr = "weak"; break; - case Qualifiers::OCL_Autoreleasing: attrStr = "autoreleasing"; break; + case Qualifiers::OCL_None: + llvm_unreachable("no ownership!"); + case Qualifiers::OCL_ExplicitNone: + attrStr = "none"; + break; + case Qualifiers::OCL_Strong: + attrStr = "strong"; + break; + case Qualifiers::OCL_Weak: + attrStr = "weak"; + break; + case Qualifiers::OCL_Autoreleasing: + attrStr = "autoreleasing"; + break; } IdentifierLoc *Arg = new (S.Context) IdentifierLoc; @@ -5864,406 +5873,399 @@ static void fillAtomicQualLoc(AtomicTypeLoc ATL, const DeclaratorChunk &Chunk) { } namespace { - class TypeSpecLocFiller : public TypeLocVisitor { - Sema &SemaRef; - ASTContext &Context; - TypeProcessingState &State; - const DeclSpec &DS; - - public: - TypeSpecLocFiller(Sema &S, ASTContext &Context, TypeProcessingState &State, - const DeclSpec &DS) - : SemaRef(S), Context(Context), State(State), DS(DS) {} - - void VisitAttributedTypeLoc(AttributedTypeLoc TL) { - Visit(TL.getModifiedLoc()); - fillAttributedTypeLoc(TL, State); - } - void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { - Visit(TL.getWrappedLoc()); - } - void VisitHLSLAttributedResourceTypeLoc(HLSLAttributedResourceTypeLoc TL) { - Visit(TL.getWrappedLoc()); - fillHLSLAttributedResourceTypeLoc(TL, State); - } - void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { - Visit(TL.getInnerLoc()); - TL.setExpansionLoc( - State.getExpansionLocForMacroQualifiedType(TL.getTypePtr())); - } - void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { - Visit(TL.getUnqualifiedLoc()); - } - // Allow to fill pointee's type locations, e.g., - // int __attr * __attr * __attr *p; - void VisitPointerTypeLoc(PointerTypeLoc TL) { Visit(TL.getNextTypeLoc()); } - void VisitTypedefTypeLoc(TypedefTypeLoc TL) { - TL.setNameLoc(DS.getTypeSpecTypeLoc()); - } - void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { - TL.setNameLoc(DS.getTypeSpecTypeLoc()); - // FIXME. We should have DS.getTypeSpecTypeEndLoc(). But, it requires - // addition field. What we have is good enough for display of location - // of 'fixit' on interface name. - TL.setNameEndLoc(DS.getEndLoc()); - } - void VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { - TypeSourceInfo *RepTInfo = nullptr; - Sema::GetTypeFromParser(DS.getRepAsType(), &RepTInfo); - TL.copy(RepTInfo->getTypeLoc()); - } - void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { - TypeSourceInfo *RepTInfo = nullptr; - Sema::GetTypeFromParser(DS.getRepAsType(), &RepTInfo); - TL.copy(RepTInfo->getTypeLoc()); - } - void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { - TypeSourceInfo *TInfo = nullptr; - Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); - - // If we got no declarator info from previous Sema routines, - // just fill with the typespec loc. - if (!TInfo) { - TL.initialize(Context, DS.getTypeSpecTypeNameLoc()); - return; - } - - TypeLoc OldTL = TInfo->getTypeLoc(); - if (TInfo->getType()->getAs()) { - ElaboratedTypeLoc ElabTL = OldTL.castAs(); - TemplateSpecializationTypeLoc NamedTL = ElabTL.getNamedTypeLoc() - .castAs(); - TL.copy(NamedTL); - } else { - TL.copy(OldTL.castAs()); - assert(TL.getRAngleLoc() == OldTL.castAs().getRAngleLoc()); - } - - } - void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { - assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr || - DS.getTypeSpecType() == DeclSpec::TST_typeof_unqualExpr); - TL.setTypeofLoc(DS.getTypeSpecTypeLoc()); - TL.setParensRange(DS.getTypeofParensRange()); +class TypeSpecLocFiller : public TypeLocVisitor { + Sema &SemaRef; + ASTContext &Context; + TypeProcessingState &State; + const DeclSpec &DS; + +public: + TypeSpecLocFiller(Sema &S, ASTContext &Context, TypeProcessingState &State, + const DeclSpec &DS) + : SemaRef(S), Context(Context), State(State), DS(DS) {} + + void VisitAttributedTypeLoc(AttributedTypeLoc TL) { + Visit(TL.getModifiedLoc()); + fillAttributedTypeLoc(TL, State); + } + void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { + Visit(TL.getWrappedLoc()); + } + void VisitHLSLAttributedResourceTypeLoc(HLSLAttributedResourceTypeLoc TL) { + Visit(TL.getWrappedLoc()); + fillHLSLAttributedResourceTypeLoc(TL, State); + } + void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { + Visit(TL.getInnerLoc()); + TL.setExpansionLoc( + State.getExpansionLocForMacroQualifiedType(TL.getTypePtr())); + } + void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { + Visit(TL.getUnqualifiedLoc()); + } + // Allow to fill pointee's type locations, e.g., + // int __attr * __attr * __attr *p; + void VisitPointerTypeLoc(PointerTypeLoc TL) { Visit(TL.getNextTypeLoc()); } + void VisitTypedefTypeLoc(TypedefTypeLoc TL) { + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + } + void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + // FIXME. We should have DS.getTypeSpecTypeEndLoc(). But, it requires + // addition field. What we have is good enough for display of location + // of 'fixit' on interface name. + TL.setNameEndLoc(DS.getEndLoc()); + } + void VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { + TypeSourceInfo *RepTInfo = nullptr; + Sema::GetTypeFromParser(DS.getRepAsType(), &RepTInfo); + TL.copy(RepTInfo->getTypeLoc()); + } + void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { + TypeSourceInfo *RepTInfo = nullptr; + Sema::GetTypeFromParser(DS.getRepAsType(), &RepTInfo); + TL.copy(RepTInfo->getTypeLoc()); + } + void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { + TypeSourceInfo *TInfo = nullptr; + Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); + + // If we got no declarator info from previous Sema routines, + // just fill with the typespec loc. + if (!TInfo) { + TL.initialize(Context, DS.getTypeSpecTypeNameLoc()); + return; } - void VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { - assert(DS.getTypeSpecType() == DeclSpec::TST_typeofType || - DS.getTypeSpecType() == DeclSpec::TST_typeof_unqualType); - TL.setTypeofLoc(DS.getTypeSpecTypeLoc()); - TL.setParensRange(DS.getTypeofParensRange()); - assert(DS.getRepAsType()); + + TypeLoc OldTL = TInfo->getTypeLoc(); + if (TInfo->getType()->getAs()) { + ElaboratedTypeLoc ElabTL = OldTL.castAs(); + TemplateSpecializationTypeLoc NamedTL = + ElabTL.getNamedTypeLoc().castAs(); + TL.copy(NamedTL); + } else { + TL.copy(OldTL.castAs()); + assert(TL.getRAngleLoc() == + OldTL.castAs().getRAngleLoc()); + } + } + void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { + assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr || + DS.getTypeSpecType() == DeclSpec::TST_typeof_unqualExpr); + TL.setTypeofLoc(DS.getTypeSpecTypeLoc()); + TL.setParensRange(DS.getTypeofParensRange()); + } + void VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { + assert(DS.getTypeSpecType() == DeclSpec::TST_typeofType || + DS.getTypeSpecType() == DeclSpec::TST_typeof_unqualType); + TL.setTypeofLoc(DS.getTypeSpecTypeLoc()); + TL.setParensRange(DS.getTypeofParensRange()); + assert(DS.getRepAsType()); + TypeSourceInfo *TInfo = nullptr; + Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); + TL.setUnmodifiedTInfo(TInfo); + } + void VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { + assert(DS.getTypeSpecType() == DeclSpec::TST_decltype); + TL.setDecltypeLoc(DS.getTypeSpecTypeLoc()); + TL.setRParenLoc(DS.getTypeofParensRange().getEnd()); + } + void VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) { + assert(DS.getTypeSpecType() == DeclSpec::TST_typename_pack_indexing); + TL.setEllipsisLoc(DS.getEllipsisLoc()); + } + void VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { + assert(DS.isTransformTypeTrait(DS.getTypeSpecType())); + TL.setKWLoc(DS.getTypeSpecTypeLoc()); + TL.setParensRange(DS.getTypeofParensRange()); + assert(DS.getRepAsType()); + TypeSourceInfo *TInfo = nullptr; + Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); + TL.setUnderlyingTInfo(TInfo); + } + void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { + // By default, use the source location of the type specifier. + TL.setBuiltinLoc(DS.getTypeSpecTypeLoc()); + if (TL.needsExtraLocalData()) { + // Set info for the written builtin specifiers. + TL.getWrittenBuiltinSpecs() = DS.getWrittenBuiltinSpecs(); + // Try to have a meaningful source location. + if (TL.getWrittenSignSpec() != TypeSpecifierSign::Unspecified) + TL.expandBuiltinRange(DS.getTypeSpecSignLoc()); + if (TL.getWrittenWidthSpec() != TypeSpecifierWidth::Unspecified) + TL.expandBuiltinRange(DS.getTypeSpecWidthRange()); + } + } + void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { + if (DS.getTypeSpecType() == TST_typename) { TypeSourceInfo *TInfo = nullptr; Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); - TL.setUnmodifiedTInfo(TInfo); + if (TInfo) + if (auto ETL = TInfo->getTypeLoc().getAs()) { + TL.copy(ETL); + return; + } } - void VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { - assert(DS.getTypeSpecType() == DeclSpec::TST_decltype); - TL.setDecltypeLoc(DS.getTypeSpecTypeLoc()); + const ElaboratedType *T = TL.getTypePtr(); + TL.setElaboratedKeywordLoc(T->getKeyword() != ElaboratedTypeKeyword::None + ? DS.getTypeSpecTypeLoc() + : SourceLocation()); + const CXXScopeSpec &SS = DS.getTypeSpecScope(); + TL.setQualifierLoc(SS.getWithLocInContext(Context)); + Visit(TL.getNextTypeLoc().getUnqualifiedLoc()); + } + void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { + assert(DS.getTypeSpecType() == TST_typename); + TypeSourceInfo *TInfo = nullptr; + Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); + assert(TInfo); + TL.copy(TInfo->getTypeLoc().castAs()); + } + void VisitDependentTemplateSpecializationTypeLoc( + DependentTemplateSpecializationTypeLoc TL) { + assert(DS.getTypeSpecType() == TST_typename); + TypeSourceInfo *TInfo = nullptr; + Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); + assert(TInfo); + TL.copy( + TInfo->getTypeLoc().castAs()); + } + void VisitAutoTypeLoc(AutoTypeLoc TL) { + assert(DS.getTypeSpecType() == TST_auto || + DS.getTypeSpecType() == TST_decltype_auto || + DS.getTypeSpecType() == TST_auto_type || + DS.getTypeSpecType() == TST_unspecified); + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + if (DS.getTypeSpecType() == TST_decltype_auto) TL.setRParenLoc(DS.getTypeofParensRange().getEnd()); - } - void VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) { - assert(DS.getTypeSpecType() == DeclSpec::TST_typename_pack_indexing); - TL.setEllipsisLoc(DS.getEllipsisLoc()); - } - void VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { - assert(DS.isTransformTypeTrait(DS.getTypeSpecType())); + if (!DS.isConstrainedAuto()) + return; + TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId(); + if (!TemplateId) + return; + + NestedNameSpecifierLoc NNS = + (DS.getTypeSpecScope().isNotEmpty() + ? DS.getTypeSpecScope().getWithLocInContext(Context) + : NestedNameSpecifierLoc()); + TemplateArgumentListInfo TemplateArgsInfo(TemplateId->LAngleLoc, + TemplateId->RAngleLoc); + if (TemplateId->NumArgs > 0) { + ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), + TemplateId->NumArgs); + SemaRef.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo); + } + DeclarationNameInfo DNI = DeclarationNameInfo( + TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(), + TemplateId->TemplateNameLoc); + + NamedDecl *FoundDecl; + if (auto TN = TemplateId->Template.get(); + UsingShadowDecl *USD = TN.getAsUsingShadowDecl()) + FoundDecl = cast(USD); + else + FoundDecl = cast_if_present(TN.getAsTemplateDecl()); + + auto *CR = ConceptReference::Create( + Context, NNS, TemplateId->TemplateKWLoc, DNI, FoundDecl, + /*NamedDecl=*/TL.getTypePtr()->getTypeConstraintConcept(), + ASTTemplateArgumentListInfo::Create(Context, TemplateArgsInfo)); + TL.setConceptReference(CR); + } + void VisitTagTypeLoc(TagTypeLoc TL) { + TL.setNameLoc(DS.getTypeSpecTypeNameLoc()); + } + void VisitAtomicTypeLoc(AtomicTypeLoc TL) { + // An AtomicTypeLoc can come from either an _Atomic(...) type specifier + // or an _Atomic qualifier. + if (DS.getTypeSpecType() == DeclSpec::TST_atomic) { TL.setKWLoc(DS.getTypeSpecTypeLoc()); TL.setParensRange(DS.getTypeofParensRange()); - assert(DS.getRepAsType()); - TypeSourceInfo *TInfo = nullptr; - Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); - TL.setUnderlyingTInfo(TInfo); - } - void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { - // By default, use the source location of the type specifier. - TL.setBuiltinLoc(DS.getTypeSpecTypeLoc()); - if (TL.needsExtraLocalData()) { - // Set info for the written builtin specifiers. - TL.getWrittenBuiltinSpecs() = DS.getWrittenBuiltinSpecs(); - // Try to have a meaningful source location. - if (TL.getWrittenSignSpec() != TypeSpecifierSign::Unspecified) - TL.expandBuiltinRange(DS.getTypeSpecSignLoc()); - if (TL.getWrittenWidthSpec() != TypeSpecifierWidth::Unspecified) - TL.expandBuiltinRange(DS.getTypeSpecWidthRange()); - } - } - void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { - if (DS.getTypeSpecType() == TST_typename) { - TypeSourceInfo *TInfo = nullptr; - Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); - if (TInfo) - if (auto ETL = TInfo->getTypeLoc().getAs()) { - TL.copy(ETL); - return; - } - } - const ElaboratedType *T = TL.getTypePtr(); - TL.setElaboratedKeywordLoc(T->getKeyword() != ElaboratedTypeKeyword::None - ? DS.getTypeSpecTypeLoc() - : SourceLocation()); - const CXXScopeSpec& SS = DS.getTypeSpecScope(); - TL.setQualifierLoc(SS.getWithLocInContext(Context)); - Visit(TL.getNextTypeLoc().getUnqualifiedLoc()); - } - void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { - assert(DS.getTypeSpecType() == TST_typename); + TypeSourceInfo *TInfo = nullptr; Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); assert(TInfo); - TL.copy(TInfo->getTypeLoc().castAs()); + TL.getValueLoc().initializeFullCopy(TInfo->getTypeLoc()); + } else { + TL.setKWLoc(DS.getAtomicSpecLoc()); + // No parens, to indicate this was spelled as an _Atomic qualifier. + TL.setParensRange(SourceRange()); + Visit(TL.getValueLoc()); } - void VisitDependentTemplateSpecializationTypeLoc( - DependentTemplateSpecializationTypeLoc TL) { - assert(DS.getTypeSpecType() == TST_typename); - TypeSourceInfo *TInfo = nullptr; - Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); - assert(TInfo); - TL.copy( - TInfo->getTypeLoc().castAs()); - } - void VisitAutoTypeLoc(AutoTypeLoc TL) { - assert(DS.getTypeSpecType() == TST_auto || - DS.getTypeSpecType() == TST_decltype_auto || - DS.getTypeSpecType() == TST_auto_type || - DS.getTypeSpecType() == TST_unspecified); - TL.setNameLoc(DS.getTypeSpecTypeLoc()); - if (DS.getTypeSpecType() == TST_decltype_auto) - TL.setRParenLoc(DS.getTypeofParensRange().getEnd()); - if (!DS.isConstrainedAuto()) - return; - TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId(); - if (!TemplateId) - return; + } - NestedNameSpecifierLoc NNS = - (DS.getTypeSpecScope().isNotEmpty() - ? DS.getTypeSpecScope().getWithLocInContext(Context) - : NestedNameSpecifierLoc()); - TemplateArgumentListInfo TemplateArgsInfo(TemplateId->LAngleLoc, - TemplateId->RAngleLoc); - if (TemplateId->NumArgs > 0) { - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), - TemplateId->NumArgs); - SemaRef.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo); - } - DeclarationNameInfo DNI = DeclarationNameInfo( - TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(), - TemplateId->TemplateNameLoc); - - NamedDecl *FoundDecl; - if (auto TN = TemplateId->Template.get(); - UsingShadowDecl *USD = TN.getAsUsingShadowDecl()) - FoundDecl = cast(USD); - else - FoundDecl = cast_if_present(TN.getAsTemplateDecl()); - - auto *CR = ConceptReference::Create( - Context, NNS, TemplateId->TemplateKWLoc, DNI, FoundDecl, - /*NamedDecl=*/TL.getTypePtr()->getTypeConstraintConcept(), - ASTTemplateArgumentListInfo::Create(Context, TemplateArgsInfo)); - TL.setConceptReference(CR); - } - void VisitTagTypeLoc(TagTypeLoc TL) { - TL.setNameLoc(DS.getTypeSpecTypeNameLoc()); - } - void VisitAtomicTypeLoc(AtomicTypeLoc TL) { - // An AtomicTypeLoc can come from either an _Atomic(...) type specifier - // or an _Atomic qualifier. - if (DS.getTypeSpecType() == DeclSpec::TST_atomic) { - TL.setKWLoc(DS.getTypeSpecTypeLoc()); - TL.setParensRange(DS.getTypeofParensRange()); - - TypeSourceInfo *TInfo = nullptr; - Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); - assert(TInfo); - TL.getValueLoc().initializeFullCopy(TInfo->getTypeLoc()); - } else { - TL.setKWLoc(DS.getAtomicSpecLoc()); - // No parens, to indicate this was spelled as an _Atomic qualifier. - TL.setParensRange(SourceRange()); - Visit(TL.getValueLoc()); - } - } + void VisitPipeTypeLoc(PipeTypeLoc TL) { + TL.setKWLoc(DS.getTypeSpecTypeLoc()); - void VisitPipeTypeLoc(PipeTypeLoc TL) { - TL.setKWLoc(DS.getTypeSpecTypeLoc()); + TypeSourceInfo *TInfo = nullptr; + Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); + TL.getValueLoc().initializeFullCopy(TInfo->getTypeLoc()); + } - TypeSourceInfo *TInfo = nullptr; - Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); - TL.getValueLoc().initializeFullCopy(TInfo->getTypeLoc()); - } + void VisitExtIntTypeLoc(BitIntTypeLoc TL) { + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + } - void VisitExtIntTypeLoc(BitIntTypeLoc TL) { - TL.setNameLoc(DS.getTypeSpecTypeLoc()); - } + void VisitDependentExtIntTypeLoc(DependentBitIntTypeLoc TL) { + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + } - void VisitDependentExtIntTypeLoc(DependentBitIntTypeLoc TL) { - TL.setNameLoc(DS.getTypeSpecTypeLoc()); - } + void VisitTypeLoc(TypeLoc TL) { + // FIXME: add other typespec types and change this to an assert. + TL.initialize(Context, DS.getTypeSpecTypeLoc()); + } +}; - void VisitTypeLoc(TypeLoc TL) { - // FIXME: add other typespec types and change this to an assert. - TL.initialize(Context, DS.getTypeSpecTypeLoc()); - } - }; +class DeclaratorLocFiller : public TypeLocVisitor { + ASTContext &Context; + TypeProcessingState &State; + const DeclaratorChunk &Chunk; - class DeclaratorLocFiller : public TypeLocVisitor { - ASTContext &Context; - TypeProcessingState &State; - const DeclaratorChunk &Chunk; +public: + DeclaratorLocFiller(ASTContext &Context, TypeProcessingState &State, + const DeclaratorChunk &Chunk) + : Context(Context), State(State), Chunk(Chunk) {} - public: - DeclaratorLocFiller(ASTContext &Context, TypeProcessingState &State, - const DeclaratorChunk &Chunk) - : Context(Context), State(State), Chunk(Chunk) {} - - void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { - llvm_unreachable("qualified type locs not expected here!"); - } - void VisitDecayedTypeLoc(DecayedTypeLoc TL) { - llvm_unreachable("decayed type locs not expected here!"); - } - void VisitArrayParameterTypeLoc(ArrayParameterTypeLoc TL) { - llvm_unreachable("array parameter type locs not expected here!"); - } - - void VisitAttributedTypeLoc(AttributedTypeLoc TL) { - fillAttributedTypeLoc(TL, State); - } - void VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) { - // nothing - } - void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { - // nothing - } - void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { - // nothing - } - void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::BlockPointer); - TL.setCaretLoc(Chunk.Loc); - } - void VisitPointerTypeLoc(PointerTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::Pointer); - TL.setStarLoc(Chunk.Loc); - } - void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::Pointer); - TL.setStarLoc(Chunk.Loc); - } - void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::MemberPointer); - const CXXScopeSpec& SS = Chunk.Mem.Scope(); - NestedNameSpecifierLoc NNSLoc = SS.getWithLocInContext(Context); - - const Type* ClsTy = TL.getClass(); - QualType ClsQT = QualType(ClsTy, 0); - TypeSourceInfo *ClsTInfo = Context.CreateTypeSourceInfo(ClsQT, 0); - // Now copy source location info into the type loc component. - TypeLoc ClsTL = ClsTInfo->getTypeLoc(); - switch (NNSLoc.getNestedNameSpecifier()->getKind()) { - case NestedNameSpecifier::Identifier: - assert(isa(ClsTy) && "Unexpected TypeLoc"); - { - DependentNameTypeLoc DNTLoc = ClsTL.castAs(); - DNTLoc.setElaboratedKeywordLoc(SourceLocation()); - DNTLoc.setQualifierLoc(NNSLoc.getPrefix()); - DNTLoc.setNameLoc(NNSLoc.getLocalBeginLoc()); - } - break; + void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { + llvm_unreachable("qualified type locs not expected here!"); + } + void VisitDecayedTypeLoc(DecayedTypeLoc TL) { + llvm_unreachable("decayed type locs not expected here!"); + } + void VisitArrayParameterTypeLoc(ArrayParameterTypeLoc TL) { + llvm_unreachable("array parameter type locs not expected here!"); + } - case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: - if (isa(ClsTy)) { - ElaboratedTypeLoc ETLoc = ClsTL.castAs(); - ETLoc.setElaboratedKeywordLoc(SourceLocation()); - ETLoc.setQualifierLoc(NNSLoc.getPrefix()); - TypeLoc NamedTL = ETLoc.getNamedTypeLoc(); - NamedTL.initializeFullCopy(NNSLoc.getTypeLoc()); - } else { - ClsTL.initializeFullCopy(NNSLoc.getTypeLoc()); - } - break; + void VisitAttributedTypeLoc(AttributedTypeLoc TL) { + fillAttributedTypeLoc(TL, State); + } + void VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) { + // nothing + } + void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { + // nothing + } + void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { + // nothing + } + void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::BlockPointer); + TL.setCaretLoc(Chunk.Loc); + } + void VisitPointerTypeLoc(PointerTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Pointer); + TL.setStarLoc(Chunk.Loc); + } + void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Pointer); + TL.setStarLoc(Chunk.Loc); + } + void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::MemberPointer); + const CXXScopeSpec &SS = Chunk.Mem.Scope(); + NestedNameSpecifierLoc NNSLoc = SS.getWithLocInContext(Context); - case NestedNameSpecifier::Namespace: - case NestedNameSpecifier::NamespaceAlias: - case NestedNameSpecifier::Global: - case NestedNameSpecifier::Super: - llvm_unreachable("Nested-name-specifier must name a type"); + const Type *ClsTy = TL.getClass(); + QualType ClsQT = QualType(ClsTy, 0); + TypeSourceInfo *ClsTInfo = Context.CreateTypeSourceInfo(ClsQT, 0); + // Now copy source location info into the type loc component. + TypeLoc ClsTL = ClsTInfo->getTypeLoc(); + switch (NNSLoc.getNestedNameSpecifier()->getKind()) { + case NestedNameSpecifier::Identifier: + assert(isa(ClsTy) && "Unexpected TypeLoc"); + { + DependentNameTypeLoc DNTLoc = ClsTL.castAs(); + DNTLoc.setElaboratedKeywordLoc(SourceLocation()); + DNTLoc.setQualifierLoc(NNSLoc.getPrefix()); + DNTLoc.setNameLoc(NNSLoc.getLocalBeginLoc()); } + break; - // Finally fill in MemberPointerLocInfo fields. - TL.setStarLoc(Chunk.Mem.StarLoc); - TL.setClassTInfo(ClsTInfo); - } - void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::Reference); - // 'Amp' is misleading: this might have been originally - /// spelled with AmpAmp. - TL.setAmpLoc(Chunk.Loc); - } - void VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::Reference); - assert(!Chunk.Ref.LValueRef); - TL.setAmpAmpLoc(Chunk.Loc); - } - void VisitArrayTypeLoc(ArrayTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::Array); - TL.setLBracketLoc(Chunk.Loc); - TL.setRBracketLoc(Chunk.EndLoc); - TL.setSizeExpr(static_cast(Chunk.Arr.NumElts)); - } - void VisitFunctionTypeLoc(FunctionTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::Function); - TL.setLocalRangeBegin(Chunk.Loc); - TL.setLocalRangeEnd(Chunk.EndLoc); - - const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun; - TL.setLParenLoc(FTI.getLParenLoc()); - TL.setRParenLoc(FTI.getRParenLoc()); - for (unsigned i = 0, e = TL.getNumParams(), tpi = 0; i != e; ++i) { - ParmVarDecl *Param = cast(FTI.Params[i].Param); - TL.setParam(tpi++, Param); + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + if (isa(ClsTy)) { + ElaboratedTypeLoc ETLoc = ClsTL.castAs(); + ETLoc.setElaboratedKeywordLoc(SourceLocation()); + ETLoc.setQualifierLoc(NNSLoc.getPrefix()); + TypeLoc NamedTL = ETLoc.getNamedTypeLoc(); + NamedTL.initializeFullCopy(NNSLoc.getTypeLoc()); + } else { + ClsTL.initializeFullCopy(NNSLoc.getTypeLoc()); } - TL.setExceptionSpecRange(FTI.getExceptionSpecRange()); - } - void VisitParenTypeLoc(ParenTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::Paren); - TL.setLParenLoc(Chunk.Loc); - TL.setRParenLoc(Chunk.EndLoc); - } - void VisitPipeTypeLoc(PipeTypeLoc TL) { - assert(Chunk.Kind == DeclaratorChunk::Pipe); - TL.setKWLoc(Chunk.Loc); - } - void VisitBitIntTypeLoc(BitIntTypeLoc TL) { - TL.setNameLoc(Chunk.Loc); - } - void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { - TL.setExpansionLoc(Chunk.Loc); - } - void VisitVectorTypeLoc(VectorTypeLoc TL) { TL.setNameLoc(Chunk.Loc); } - void VisitDependentVectorTypeLoc(DependentVectorTypeLoc TL) { - TL.setNameLoc(Chunk.Loc); - } - void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { - TL.setNameLoc(Chunk.Loc); - } - void VisitAtomicTypeLoc(AtomicTypeLoc TL) { - fillAtomicQualLoc(TL, Chunk); - } - void - VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) { - TL.setNameLoc(Chunk.Loc); - } - void VisitMatrixTypeLoc(MatrixTypeLoc TL) { - fillMatrixTypeLoc(TL, Chunk.getAttrs()); + break; + + case NestedNameSpecifier::Namespace: + case NestedNameSpecifier::NamespaceAlias: + case NestedNameSpecifier::Global: + case NestedNameSpecifier::Super: + llvm_unreachable("Nested-name-specifier must name a type"); } - void VisitTypeLoc(TypeLoc TL) { - llvm_unreachable("unsupported TypeLoc kind in declarator!"); + // Finally fill in MemberPointerLocInfo fields. + TL.setStarLoc(Chunk.Mem.StarLoc); + TL.setClassTInfo(ClsTInfo); + } + void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Reference); + // 'Amp' is misleading: this might have been originally + /// spelled with AmpAmp. + TL.setAmpLoc(Chunk.Loc); + } + void VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Reference); + assert(!Chunk.Ref.LValueRef); + TL.setAmpAmpLoc(Chunk.Loc); + } + void VisitArrayTypeLoc(ArrayTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Array); + TL.setLBracketLoc(Chunk.Loc); + TL.setRBracketLoc(Chunk.EndLoc); + TL.setSizeExpr(static_cast(Chunk.Arr.NumElts)); + } + void VisitFunctionTypeLoc(FunctionTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Function); + TL.setLocalRangeBegin(Chunk.Loc); + TL.setLocalRangeEnd(Chunk.EndLoc); + + const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun; + TL.setLParenLoc(FTI.getLParenLoc()); + TL.setRParenLoc(FTI.getRParenLoc()); + for (unsigned i = 0, e = TL.getNumParams(), tpi = 0; i != e; ++i) { + ParmVarDecl *Param = cast(FTI.Params[i].Param); + TL.setParam(tpi++, Param); } - }; + TL.setExceptionSpecRange(FTI.getExceptionSpecRange()); + } + void VisitParenTypeLoc(ParenTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Paren); + TL.setLParenLoc(Chunk.Loc); + TL.setRParenLoc(Chunk.EndLoc); + } + void VisitPipeTypeLoc(PipeTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Pipe); + TL.setKWLoc(Chunk.Loc); + } + void VisitBitIntTypeLoc(BitIntTypeLoc TL) { TL.setNameLoc(Chunk.Loc); } + void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { + TL.setExpansionLoc(Chunk.Loc); + } + void VisitVectorTypeLoc(VectorTypeLoc TL) { TL.setNameLoc(Chunk.Loc); } + void VisitDependentVectorTypeLoc(DependentVectorTypeLoc TL) { + TL.setNameLoc(Chunk.Loc); + } + void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { TL.setNameLoc(Chunk.Loc); } + void VisitAtomicTypeLoc(AtomicTypeLoc TL) { fillAtomicQualLoc(TL, Chunk); } + void VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) { + TL.setNameLoc(Chunk.Loc); + } + void VisitMatrixTypeLoc(MatrixTypeLoc TL) { + fillMatrixTypeLoc(TL, Chunk.getAttrs()); + } + + void VisitTypeLoc(TypeLoc TL) { + llvm_unreachable("unsupported TypeLoc kind in declarator!"); + } +}; } // end anonymous namespace static void @@ -6291,8 +6293,8 @@ fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL, /// conversion function), this pointer will refer to a type source information /// for that return type. static TypeSourceInfo * -GetTypeSourceInfoForDeclarator(TypeProcessingState &State, - QualType T, TypeSourceInfo *ReturnTypeInfo) { +GetTypeSourceInfoForDeclarator(TypeProcessingState &State, QualType T, + TypeSourceInfo *ReturnTypeInfo) { Sema &S = State.getSema(); Declarator &D = State.getDeclarator(); @@ -6389,8 +6391,8 @@ ParsedType Sema::CreateParsedType(QualType T, TypeSourceInfo *TInfo) { void LocInfoType::getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const { llvm_unreachable("LocInfoType leaked into the type system; an opaque TypeTy*" - " was used directly instead of getting the QualType through" - " GetTypeFromParser"); + " was used directly instead of getting the QualType through" + " GetTypeFromParser"); } TypeResult Sema::ActOnTypeName(Declarator &D) { @@ -6565,8 +6567,8 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type, // Check the attribute arguments. if (Attr.getNumArgs() != 1) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr - << 1; + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) + << Attr << 1; Attr.setInvalid(); return; } @@ -6664,8 +6666,8 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, S.getSourceManager().getImmediateExpansionRange(AttrLoc).getBegin(); if (!attr.isArgIdent(0)) { - S.Diag(AttrLoc, diag::err_attribute_argument_type) << attr - << AANT_ArgumentString; + S.Diag(AttrLoc, diag::err_attribute_argument_type) + << attr << AANT_ArgumentString; attr.setInvalid(); return true; } @@ -6688,8 +6690,7 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, // Just ignore lifetime attributes other than __weak and __unsafe_unretained // outside of ARC mode. - if (!S.getLangOpts().ObjCAutoRefCount && - lifetime != Qualifiers::OCL_Weak && + if (!S.getLangOpts().ObjCAutoRefCount && lifetime != Qualifiers::OCL_Weak && lifetime != Qualifiers::OCL_ExplicitNone) { return true; } @@ -6697,12 +6698,11 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, SplitQualType underlyingType = type.split(); // Check for redundant/conflicting ownership qualifiers. - if (Qualifiers::ObjCLifetime previousLifetime - = type.getQualifiers().getObjCLifetime()) { + if (Qualifiers::ObjCLifetime previousLifetime = + type.getQualifiers().getObjCLifetime()) { // If it's written directly, that's an error. if (S.Context.hasDirectOwnershipQualifier(type)) { - S.Diag(AttrLoc, diag::err_attr_objc_ownership_redundant) - << type; + S.Diag(AttrLoc, diag::err_attr_objc_ownership_redundant) << type; return true; } @@ -6728,12 +6728,18 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, case Qualifiers::OCL_None: case Qualifiers::OCL_ExplicitNone: break; - case Qualifiers::OCL_Strong: name = "__strong"; break; - case Qualifiers::OCL_Weak: name = "__weak"; break; - case Qualifiers::OCL_Autoreleasing: name = "__autoreleasing"; break; + case Qualifiers::OCL_Strong: + name = "__strong"; + break; + case Qualifiers::OCL_Weak: + name = "__weak"; + break; + case Qualifiers::OCL_Autoreleasing: + name = "__autoreleasing"; + break; } - S.Diag(AttrLoc, diag::warn_type_attribute_wrong_type) << name - << TDS_ObjCObjOrBlock << type; + S.Diag(AttrLoc, diag::warn_type_attribute_wrong_type) + << name << TDS_ObjCObjOrBlock << type; } // Don't actually add the __unsafe_unretained qualifier in non-ARC files, @@ -6750,8 +6756,8 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, if (!S.getLangOpts().ObjCAutoRefCount && lifetime == Qualifiers::OCL_ExplicitNone) { type = state.getAttributedType( - createSimpleAttr(S.Context, attr), - type, type); + createSimpleAttr(S.Context, attr), type, + type); return true; } @@ -6767,26 +6773,25 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, origType, type); } - auto diagnoseOrDelay = [](Sema &S, SourceLocation loc, - unsigned diagnostic, QualType type) { + auto diagnoseOrDelay = [](Sema &S, SourceLocation loc, unsigned diagnostic, + QualType type) { if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { - S.DelayedDiagnostics.add( - sema::DelayedDiagnostic::makeForbiddenType( - S.getSourceManager().getExpansionLoc(loc), - diagnostic, type, /*ignored*/ 0)); + S.DelayedDiagnostics.add(sema::DelayedDiagnostic::makeForbiddenType( + S.getSourceManager().getExpansionLoc(loc), diagnostic, type, + /*ignored*/ 0)); } else { S.Diag(loc, diagnostic); } }; // Sometimes, __weak isn't allowed. - if (lifetime == Qualifiers::OCL_Weak && - !S.getLangOpts().ObjCWeak && !NonObjCPointer) { + if (lifetime == Qualifiers::OCL_Weak && !S.getLangOpts().ObjCWeak && + !NonObjCPointer) { // Use a specialized diagnostic if the runtime just doesn't support them. unsigned diagnostic = - (S.getLangOpts().ObjCWeakRuntime ? diag::err_arc_weak_disabled - : diag::err_arc_weak_no_runtime); + (S.getLangOpts().ObjCWeakRuntime ? diag::err_arc_weak_disabled + : diag::err_arc_weak_no_runtime); // In any case, delay the diagnostic until we know what we're parsing. diagnoseOrDelay(S, AttrLoc, diagnostic, type); @@ -6799,7 +6804,7 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, // objc_arc_weak_reference_unavailable if (lifetime == Qualifiers::OCL_Weak) { if (const ObjCObjectPointerType *ObjT = - type->getAs()) { + type->getAs()) { if (ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl()) { if (Class->isArcWeakrefUnavailable()) { S.Diag(AttrLoc, diag::err_arc_unsupported_weak_class); @@ -6822,8 +6827,7 @@ static bool handleObjCGCTypeAttr(TypeProcessingState &state, ParsedAttr &attr, Sema &S = state.getSema(); // Delay if this isn't some kind of pointer. - if (!type->isPointerType() && - !type->isObjCObjectPointerType() && + if (!type->isPointerType() && !type->isObjCObjectPointerType() && !type->isBlockPointerType()) return false; @@ -6842,8 +6846,8 @@ static bool handleObjCGCTypeAttr(TypeProcessingState &state, ParsedAttr &attr, } Qualifiers::GC GCAttr; if (attr.getNumArgs() > 1) { - S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << attr - << 1; + S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) + << attr << 1; attr.setInvalid(); return true; } @@ -6872,182 +6876,186 @@ static bool handleObjCGCTypeAttr(TypeProcessingState &state, ParsedAttr &attr, } namespace { - /// A helper class to unwrap a type down to a function for the - /// purposes of applying attributes there. - /// - /// Use: - /// FunctionTypeUnwrapper unwrapped(SemaRef, T); - /// if (unwrapped.isFunctionType()) { - /// const FunctionType *fn = unwrapped.get(); - /// // change fn somehow - /// T = unwrapped.wrap(fn); - /// } - struct FunctionTypeUnwrapper { - enum WrapKind { - Desugar, - Attributed, - Parens, - Array, - Pointer, - BlockPointer, - Reference, - MemberPointer, - MacroQualified, - }; - - QualType Original; - const FunctionType *Fn; - SmallVector Stack; - - FunctionTypeUnwrapper(Sema &S, QualType T) : Original(T) { - while (true) { - const Type *Ty = T.getTypePtr(); - if (isa(Ty)) { - Fn = cast(Ty); - return; - } else if (isa(Ty)) { - T = cast(Ty)->getInnerType(); - Stack.push_back(Parens); - } else if (isa(Ty) || isa(Ty) || - isa(Ty)) { - T = cast(Ty)->getElementType(); - Stack.push_back(Array); - } else if (isa(Ty)) { - T = cast(Ty)->getPointeeType(); - Stack.push_back(Pointer); - } else if (isa(Ty)) { - T = cast(Ty)->getPointeeType(); - Stack.push_back(BlockPointer); - } else if (isa(Ty)) { - T = cast(Ty)->getPointeeType(); - Stack.push_back(MemberPointer); - } else if (isa(Ty)) { - T = cast(Ty)->getPointeeType(); - Stack.push_back(Reference); - } else if (isa(Ty)) { - T = cast(Ty)->getEquivalentType(); - Stack.push_back(Attributed); - } else if (isa(Ty)) { - T = cast(Ty)->getUnderlyingType(); - Stack.push_back(MacroQualified); - } else { - const Type *DTy = Ty->getUnqualifiedDesugaredType(); - if (Ty == DTy) { - Fn = nullptr; - return; - } +/// A helper class to unwrap a type down to a function for the +/// purposes of applying attributes there. +/// +/// Use: +/// FunctionTypeUnwrapper unwrapped(SemaRef, T); +/// if (unwrapped.isFunctionType()) { +/// const FunctionType *fn = unwrapped.get(); +/// // change fn somehow +/// T = unwrapped.wrap(fn); +/// } +struct FunctionTypeUnwrapper { + enum WrapKind { + Desugar, + Attributed, + Parens, + Array, + Pointer, + BlockPointer, + Reference, + MemberPointer, + MacroQualified, + }; - T = QualType(DTy, 0); - Stack.push_back(Desugar); + QualType Original; + const FunctionType *Fn; + SmallVector Stack; + + FunctionTypeUnwrapper(Sema &S, QualType T) : Original(T) { + while (true) { + const Type *Ty = T.getTypePtr(); + if (isa(Ty)) { + Fn = cast(Ty); + return; + } else if (isa(Ty)) { + T = cast(Ty)->getInnerType(); + Stack.push_back(Parens); + } else if (isa(Ty) || isa(Ty) || + isa(Ty)) { + T = cast(Ty)->getElementType(); + Stack.push_back(Array); + } else if (isa(Ty)) { + T = cast(Ty)->getPointeeType(); + Stack.push_back(Pointer); + } else if (isa(Ty)) { + T = cast(Ty)->getPointeeType(); + Stack.push_back(BlockPointer); + } else if (isa(Ty)) { + T = cast(Ty)->getPointeeType(); + Stack.push_back(MemberPointer); + } else if (isa(Ty)) { + T = cast(Ty)->getPointeeType(); + Stack.push_back(Reference); + } else if (isa(Ty)) { + T = cast(Ty)->getEquivalentType(); + Stack.push_back(Attributed); + } else if (isa(Ty)) { + T = cast(Ty)->getUnderlyingType(); + Stack.push_back(MacroQualified); + } else { + const Type *DTy = Ty->getUnqualifiedDesugaredType(); + if (Ty == DTy) { + Fn = nullptr; + return; } + + T = QualType(DTy, 0); + Stack.push_back(Desugar); } } + } - bool isFunctionType() const { return (Fn != nullptr); } - const FunctionType *get() const { return Fn; } - - QualType wrap(Sema &S, const FunctionType *New) { - // If T wasn't modified from the unwrapped type, do nothing. - if (New == get()) return Original; + bool isFunctionType() const { return (Fn != nullptr); } + const FunctionType *get() const { return Fn; } - Fn = New; - return wrap(S.Context, Original, 0); - } + QualType wrap(Sema &S, const FunctionType *New) { + // If T wasn't modified from the unwrapped type, do nothing. + if (New == get()) + return Original; - private: - QualType wrap(ASTContext &C, QualType Old, unsigned I) { - if (I == Stack.size()) - return C.getQualifiedType(Fn, Old.getQualifiers()); + Fn = New; + return wrap(S.Context, Original, 0); + } - // Build up the inner type, applying the qualifiers from the old - // type to the new type. - SplitQualType SplitOld = Old.split(); +private: + QualType wrap(ASTContext &C, QualType Old, unsigned I) { + if (I == Stack.size()) + return C.getQualifiedType(Fn, Old.getQualifiers()); - // As a special case, tail-recurse if there are no qualifiers. - if (SplitOld.Quals.empty()) - return wrap(C, SplitOld.Ty, I); - return C.getQualifiedType(wrap(C, SplitOld.Ty, I), SplitOld.Quals); - } + // Build up the inner type, applying the qualifiers from the old + // type to the new type. + SplitQualType SplitOld = Old.split(); - QualType wrap(ASTContext &C, const Type *Old, unsigned I) { - if (I == Stack.size()) return QualType(Fn, 0); + // As a special case, tail-recurse if there are no qualifiers. + if (SplitOld.Quals.empty()) + return wrap(C, SplitOld.Ty, I); + return C.getQualifiedType(wrap(C, SplitOld.Ty, I), SplitOld.Quals); + } - switch (static_cast(Stack[I++])) { - case Desugar: - // This is the point at which we potentially lose source - // information. - return wrap(C, Old->getUnqualifiedDesugaredType(), I); + QualType wrap(ASTContext &C, const Type *Old, unsigned I) { + if (I == Stack.size()) + return QualType(Fn, 0); - case Attributed: - return wrap(C, cast(Old)->getEquivalentType(), I); + switch (static_cast(Stack[I++])) { + case Desugar: + // This is the point at which we potentially lose source + // information. + return wrap(C, Old->getUnqualifiedDesugaredType(), I); - case Parens: { - QualType New = wrap(C, cast(Old)->getInnerType(), I); - return C.getParenType(New); - } + case Attributed: + return wrap(C, cast(Old)->getEquivalentType(), I); - case MacroQualified: - return wrap(C, cast(Old)->getUnderlyingType(), I); + case Parens: { + QualType New = wrap(C, cast(Old)->getInnerType(), I); + return C.getParenType(New); + } - case Array: { - if (const auto *CAT = dyn_cast(Old)) { - QualType New = wrap(C, CAT->getElementType(), I); - return C.getConstantArrayType(New, CAT->getSize(), CAT->getSizeExpr(), - CAT->getSizeModifier(), - CAT->getIndexTypeCVRQualifiers()); - } + case MacroQualified: + return wrap(C, cast(Old)->getUnderlyingType(), I); - if (const auto *VAT = dyn_cast(Old)) { - QualType New = wrap(C, VAT->getElementType(), I); - return C.getVariableArrayType( - New, VAT->getSizeExpr(), VAT->getSizeModifier(), - VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange()); - } - - const auto *IAT = cast(Old); - QualType New = wrap(C, IAT->getElementType(), I); - return C.getIncompleteArrayType(New, IAT->getSizeModifier(), - IAT->getIndexTypeCVRQualifiers()); + case Array: { + if (const auto *CAT = dyn_cast(Old)) { + QualType New = wrap(C, CAT->getElementType(), I); + return C.getConstantArrayType(New, CAT->getSize(), CAT->getSizeExpr(), + CAT->getSizeModifier(), + CAT->getIndexTypeCVRQualifiers()); } - case Pointer: { - QualType New = wrap(C, cast(Old)->getPointeeType(), I); - return C.getPointerType(New); + if (const auto *VAT = dyn_cast(Old)) { + QualType New = wrap(C, VAT->getElementType(), I); + return C.getVariableArrayType( + New, VAT->getSizeExpr(), VAT->getSizeModifier(), + VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange()); } - case BlockPointer: { - QualType New = wrap(C, cast(Old)->getPointeeType(),I); - return C.getBlockPointerType(New); - } + const auto *IAT = cast(Old); + QualType New = wrap(C, IAT->getElementType(), I); + return C.getIncompleteArrayType(New, IAT->getSizeModifier(), + IAT->getIndexTypeCVRQualifiers()); + } - case MemberPointer: { - const MemberPointerType *OldMPT = cast(Old); - QualType New = wrap(C, OldMPT->getPointeeType(), I); - return C.getMemberPointerType(New, OldMPT->getClass()); - } + case Pointer: { + QualType New = wrap(C, cast(Old)->getPointeeType(), I); + return C.getPointerType(New); + } - case Reference: { - const ReferenceType *OldRef = cast(Old); - QualType New = wrap(C, OldRef->getPointeeType(), I); - if (isa(OldRef)) - return C.getLValueReferenceType(New, OldRef->isSpelledAsLValue()); - else - return C.getRValueReferenceType(New); - } - } + case BlockPointer: { + QualType New = wrap(C, cast(Old)->getPointeeType(), I); + return C.getBlockPointerType(New); + } - llvm_unreachable("unknown wrapping kind"); + case MemberPointer: { + const MemberPointerType *OldMPT = cast(Old); + QualType New = wrap(C, OldMPT->getPointeeType(), I); + return C.getMemberPointerType(New, OldMPT->getClass()); } - }; + + case Reference: { + const ReferenceType *OldRef = cast(Old); + QualType New = wrap(C, OldRef->getPointeeType(), I); + if (isa(OldRef)) + return C.getLValueReferenceType(New, OldRef->isSpelledAsLValue()); + else + return C.getRValueReferenceType(New); + } + } + + llvm_unreachable("unknown wrapping kind"); + } +}; } // end anonymous namespace static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State, - ParsedAttr &PAttr, QualType &Type) { + ParsedAttr &PAttr, + QualType &Type) { Sema &S = State.getSema(); Attr *A; switch (PAttr.getKind()) { - default: llvm_unreachable("Unknown attribute kind"); + default: + llvm_unreachable("Unknown attribute kind"); case ParsedAttr::AT_Ptr32: A = createSimpleAttr(S.Context, PAttr); break; @@ -7412,14 +7420,13 @@ static bool checkObjCKindOfType(TypeProcessingState &state, QualType &type, // Find out if it's an Objective-C object or object pointer type; const ObjCObjectPointerType *ptrType = type->getAs(); - const ObjCObjectType *objType = ptrType ? ptrType->getObjectType() - : type->getAs(); + const ObjCObjectType *objType = + ptrType ? ptrType->getObjectType() : type->getAs(); // If not, we can't apply __kindof. if (!objType) { // FIXME: Handle dependent types that aren't yet object types. - S.Diag(attr.getLoc(), diag::err_objc_kindof_nonobject) - << type; + S.Diag(attr.getLoc(), diag::err_objc_kindof_nonobject) << type; return true; } @@ -7476,18 +7483,18 @@ static bool distributeNullabilityTypeAttr(TypeProcessingState &state, PK_MemberPointer, PK_FunctionPointer, PK_MemberFunctionPointer, - } pointerKind - = chunk.Kind == DeclaratorChunk::Pointer ? (inFunction ? PK_FunctionPointer - : PK_Pointer) - : chunk.Kind == DeclaratorChunk::BlockPointer ? PK_BlockPointer - : inFunction? PK_MemberFunctionPointer : PK_MemberPointer; - - auto diag = state.getSema().Diag(attr.getLoc(), - diag::warn_nullability_declspec) - << DiagNullabilityKind(mapNullabilityAttrKind(attr.getKind()), - attr.isContextSensitiveKeywordAttribute()) - << type - << static_cast(pointerKind); + } pointerKind = chunk.Kind == DeclaratorChunk::Pointer + ? (inFunction ? PK_FunctionPointer : PK_Pointer) + : chunk.Kind == DeclaratorChunk::BlockPointer + ? PK_BlockPointer + : inFunction ? PK_MemberFunctionPointer + : PK_MemberPointer; + + auto diag = + state.getSema().Diag(attr.getLoc(), diag::warn_nullability_declspec) + << DiagNullabilityKind(mapNullabilityAttrKind(attr.getKind()), + attr.isContextSensitiveKeywordAttribute()) + << type << static_cast(pointerKind); // FIXME: MemberPointer chunks don't carry the location of the *. if (chunk.Kind != DeclaratorChunk::MemberPointer) { @@ -7506,7 +7513,7 @@ static bool distributeNullabilityTypeAttr(TypeProcessingState &state, // Move it to the outermost pointer, member pointer, or block // pointer declarator. for (unsigned i = state.getCurrentChunkIndex(); i != 0; --i) { - DeclaratorChunk &chunk = declarator.getTypeObject(i-1); + DeclaratorChunk &chunk = declarator.getTypeObject(i - 1); switch (chunk.Kind) { case DeclaratorChunk::Pointer: case DeclaratorChunk::BlockPointer: @@ -7520,9 +7527,9 @@ static bool distributeNullabilityTypeAttr(TypeProcessingState &state, case DeclaratorChunk::Function: // Try to move past the return type to a function/block/member // function pointer. - if (DeclaratorChunk *dest = maybeMovePastReturnType( - declarator, i, - /*onlyBlockPointers=*/false)) { + if (DeclaratorChunk *dest = + maybeMovePastReturnType(declarator, i, + /*onlyBlockPointers=*/false)) { return moveToChunk(*dest, true); } @@ -7818,7 +7825,8 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr, // ns_returns_retained is not always a type attribute, but if we got // here, we're treating it as one right now. if (attr.getKind() == ParsedAttr::AT_NSReturnsRetained) { - if (attr.getNumArgs()) return true; + if (attr.getNumArgs()) + return true; // Delay if this is not a function type. if (!unwrapped.isFunctionType()) @@ -7832,13 +7840,14 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr, // Only actually change the underlying type in ARC builds. QualType origType = type; if (state.getSema().getLangOpts().ObjCAutoRefCount) { - FunctionType::ExtInfo EI - = unwrapped.get()->getExtInfo().withProducesResult(true); - type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI)); + FunctionType::ExtInfo EI = + unwrapped.get()->getExtInfo().withProducesResult(true); + type = + unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI)); } type = state.getAttributedType( - createSimpleAttr(S.Context, attr), - origType, type); + createSimpleAttr(S.Context, attr), origType, + type); return true; } @@ -7872,7 +7881,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr, return true; FunctionType::ExtInfo EI = - unwrapped.get()->getExtInfo().withNoCfCheck(true); + unwrapped.get()->getExtInfo().withNoCfCheck(true); type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI)); return true; } @@ -7897,8 +7906,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr, return true; } - FunctionType::ExtInfo EI = - unwrapped.get()->getExtInfo().withRegParm(value); + FunctionType::ExtInfo EI = unwrapped.get()->getExtInfo().withRegParm(value); type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI)); return true; } @@ -7924,8 +7932,9 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr, if (!FnTy) { // SME ACLE attributes are not supported on K&R-style unprototyped C // functions. - S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) << - attr << attr.isRegularKeywordAttribute() << ExpectedFunctionWithProtoType; + S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) + << attr << attr.isRegularKeywordAttribute() + << ExpectedFunctionWithProtoType; attr.setInvalid(); return false; } @@ -8028,7 +8037,8 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr, } // Delay if the type didn't work out to a function. - if (!unwrapped.isFunctionType()) return false; + if (!unwrapped.isFunctionType()) + return false; // Otherwise, a calling convention. CallingConv CC; @@ -8093,7 +8103,7 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr, } else { auto EI = unwrapped.get()->getExtInfo().withCallingConv(CC); Equivalent = - unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI)); + unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI)); } type = state.getAttributedType(CCAttr, type, Equivalent); return true; @@ -8117,8 +8127,8 @@ void Sema::adjustMemberFunctionCC(QualType &T, bool HasThisPointer, bool IsCtorOrDtor, SourceLocation Loc) { FunctionTypeUnwrapper Unwrapped(*this, T); const FunctionType *FT = Unwrapped.get(); - bool IsVariadic = (isa(FT) && - cast(FT)->isVariadic()); + bool IsVariadic = + (isa(FT) && cast(FT)->isVariadic()); CallingConv CurCC = FT->getCallConv(); CallingConv ToCC = Context.getDefaultCallingConvention(IsVariadic, HasThisPointer); @@ -8135,7 +8145,7 @@ void Sema::adjustMemberFunctionCC(QualType &T, bool HasThisPointer, Diag(Loc, diag::warn_cconv_unsupported) << FunctionType::getNameForCallConv(CurCC) << (int)Sema::CallingConventionIgnoredReason::ConstructorDestructor; - // Default adjustment. + // Default adjustment. } else { // Only adjust types with the default convention. For example, on Windows // we should adjust a __cdecl type to __thiscall for instance methods, and a @@ -8166,8 +8176,8 @@ static void HandleVectorSizeAttr(QualType &CurType, const ParsedAttr &Attr, Sema &S) { // Check the attribute arguments. if (Attr.getNumArgs() != 1) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr - << 1; + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) + << Attr << 1; Attr.setInvalid(); return; } @@ -8186,8 +8196,8 @@ static void HandleExtVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, Sema &S) { // check the attribute arguments. if (Attr.getNumArgs() != 1) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr - << 1; + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) + << Attr << 1; return; } @@ -8502,14 +8512,15 @@ static void HandleRISCVRVVVectorBitsTypeAttr(QualType &CurType, /// Handle OpenCL Access Qualifier Attribute. static void HandleOpenCLAccessAttr(QualType &CurType, const ParsedAttr &Attr, Sema &S) { - // OpenCL v2.0 s6.6 - Access qualifier can be used only for image and pipe type. + // OpenCL v2.0 s6.6 - Access qualifier can be used only for image and pipe + // type. if (!(CurType->isImageType() || CurType->isPipeType())) { S.Diag(Attr.getLoc(), diag::err_opencl_invalid_access_qualifier); Attr.setInvalid(); return; } - if (const TypedefType* TypedefTy = CurType->getAs()) { + if (const TypedefType *TypedefTy = CurType->getAs()) { QualType BaseTy = TypedefTy->desugar(); std::string PrevAccessQual; @@ -8521,14 +8532,14 @@ static void HandleOpenCLAccessAttr(QualType &CurType, const ParsedAttr &Attr, } else { PrevAccessQual = "read_only"; } - } else if (const BuiltinType* ImgType = BaseTy->getAs()) { + } else if (const BuiltinType *ImgType = BaseTy->getAs()) { switch (ImgType->getKind()) { - #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ - case BuiltinType::Id: \ - PrevAccessQual = #Access; \ - break; - #include "clang/Basic/OpenCLImageTypes.def" +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: \ + PrevAccessQual = #Access; \ + break; +#include "clang/Basic/OpenCLImageTypes.def" default: llvm_unreachable("Unable to find corresponding image type."); } @@ -8539,14 +8550,15 @@ static void HandleOpenCLAccessAttr(QualType &CurType, const ParsedAttr &Attr, if (PrevAccessQual == AttrName.ltrim("_")) { // Duplicated qualifiers S.Diag(Attr.getLoc(), diag::warn_duplicate_declspec) - << AttrName << Attr.getRange(); + << AttrName << Attr.getRange(); } else { // Contradicting qualifiers S.Diag(Attr.getLoc(), diag::err_opencl_multiple_access_qualifiers); } S.Diag(TypedefTy->getDecl()->getBeginLoc(), - diag::note_opencl_typedef_access_qualifier) << PrevAccessQual; + diag::note_opencl_typedef_access_qualifier) + << PrevAccessQual; } else if (CurType->isPipeType()) { if (Attr.getSemanticSpelling() == OpenCLAccessAttr::Keyword_write_only) { QualType ElemType = CurType->castAs()->getElementType(); @@ -8605,8 +8617,7 @@ static void HandleAnnotateTypeAttr(TypeProcessingState &State, } static void HandleLifetimeBoundAttr(TypeProcessingState &State, - QualType &CurType, - ParsedAttr &Attr) { + QualType &CurType, ParsedAttr &Attr) { if (State.getDeclarator().isDeclarationOfFunction()) { CurType = State.getAttributedType( createSimpleAttr(State.getSema().Context, Attr), @@ -8834,7 +8845,6 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, attr.setUsedAsTypeAttr(); break; - NULLABILITY_TYPE_ATTRS_CASELIST: // Either add nullability here or try to distribute it. We // don't want to distribute the nullability specifier past any @@ -8882,8 +8892,8 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, break; case ParsedAttr::AT_NoThrow: - // Exception Specifications aren't generally supported in C mode throughout - // clang, so revert to attribute-based handling for C. + // Exception Specifications aren't generally supported in C mode + // throughout clang, so revert to attribute-based handling for C. if (!state.getSema().getLangOpts().CPlusPlus) break; [[fallthrough]]; @@ -9072,9 +9082,8 @@ bool Sema::hasStructuralCompatLayout(Decl *D, Decl *Suggested) { // and isolate from other C++ specific checks. StructuralEquivalenceContext Ctx( D->getASTContext(), Suggested->getASTContext(), NonEquivalentDecls, - StructuralEquivalenceKind::Default, - false /*StrictTypeSpelling*/, true /*Complain*/, - true /*ErrorOnTagTypeMismatch*/); + StructuralEquivalenceKind::Default, false /*StrictTypeSpelling*/, + true /*Complain*/, true /*ErrorOnTagTypeMismatch*/); return Ctx.IsEquivalent(D, Suggested); } @@ -9303,9 +9312,9 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T, // Give the external AST source a chance to complete the type. if (auto *Source = Context.getExternalSource()) { if (Tag && Tag->hasExternalLexicalStorage()) - Source->CompleteType(Tag); + Source->CompleteType(Tag); if (IFace && IFace->hasExternalLexicalStorage()) - Source->CompleteType(IFace); + Source->CompleteType(IFace); // If the external source completed the type, go through the motions // again to ensure we're allowed to use the completed type. if (!T->isIncompleteType()) @@ -9324,7 +9333,7 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T, // an instantiated class template specialization). // FIXME: Can this ever happen? } else if (auto *ClassTemplateSpec = - dyn_cast(RD)) { + dyn_cast(RD)) { if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared) { runWithSufficientStackSpace(Loc, [&] { Diagnosed = InstantiateClassTemplateSpecialization( @@ -9376,10 +9385,10 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T, // If the type was a forward declaration of a class/struct/union // type, produce a note. if (Tag && !Tag->isInvalidDecl() && !Tag->getLocation().isInvalid()) - Diag(Tag->getLocation(), - Tag->isBeingDefined() ? diag::note_type_being_defined - : diag::note_forward_declaration) - << Context.getTagDeclType(Tag); + Diag(Tag->getLocation(), Tag->isBeingDefined() + ? diag::note_type_being_defined + : diag::note_forward_declaration) + << Context.getTagDeclType(Tag); // If the Objective-C class was a forward declaration, produce a note. if (IFace && !IFace->isInvalidDecl() && !IFace->getLocation().isInvalid()) @@ -9412,7 +9421,8 @@ static unsigned getLiteralDiagFromTagKind(TagTypeKind Tag) { return 1; case TagTypeKind::Class: return 2; - default: llvm_unreachable("Invalid tag kind for literal type diagnostic!"); + default: + llvm_unreachable("Invalid tag kind for literal type diagnostic!"); } } @@ -9455,7 +9465,7 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T, // of constexpr constructors. if (RD->getNumVBases()) { Diag(RD->getLocation(), diag::note_non_literal_virtual_base) - << getLiteralDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases(); + << getLiteralDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases(); for (const auto &I : RD->vbases()) Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here) << I.getSourceRange(); @@ -9474,8 +9484,7 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T, if (!I->getType()->isLiteralType(Context) || I->getType().isVolatileQualified()) { Diag(I->getLocation(), diag::note_non_literal_field) - << RD << I << I->getType() - << I->getType().isVolatileQualified(); + << RD << I << I->getType() << I->getType().isVolatileQualified(); return true; } } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 1465bba87724b..11d4dd2951c07 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1452,6 +1452,19 @@ class TreeTransform { SourceLocation RParenLoc, Stmt *Body) { return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body); } + + /// Build a new while statement. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + StmtResult RebuildWhenStmt(SourceLocation WhenLoc, + Sema::ConditionResult Cond, + Stmt *Body) { + IdentifierInfo *VarName = nullptr; + SourceLocation VarLoc; + bool IsAccept = false; + return getSema().ActOnWhenStatement(WhenLoc, Cond, IsAccept, VarName, VarLoc, Body); + } /// Build a new do-while statement. /// @@ -8244,6 +8257,32 @@ TreeTransform::TransformWhileStmt(WhileStmt *S) { Cond, S->getRParenLoc(), Body.get()); } +template +StmtResult TreeTransform::TransformWhenStmt(WhenStmt *S) { + // Transform the condition expression + Sema::ConditionResult Cond = getDerived().TransformCondition( + S->getWhenLoc(), /*Var=*/nullptr, S->getCondition(), + Sema::ConditionKind::Boolean); + if (Cond.isInvalid()) + return StmtError(); + + // Transform the body statement + StmtResult Body = getDerived().TransformStmt(S->getBody()); + if (Body.isInvalid()) + return StmtError(); + + // If there are no modifications, return the original node + if (!getDerived().AlwaysRebuild() && + Cond.get().second == S->getCondition() && + Body.get() == S->getBody()) { + return S; + } + + // Rebuild the transformed WhenStmt + return getDerived().RebuildWhenStmt(S->getBeginLoc(), Cond, Body.get()); +} + + template StmtResult TreeTransform::TransformDoStmt(DoStmt *S) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index c39a1950a6cf2..e907a6e7e2a40 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -289,6 +289,15 @@ void ASTStmtReader::VisitWhileStmt(WhileStmt *S) { S->setRParenLoc(readSourceLocation()); } +void ASTStmtReader::VisitWhenStmt(WhenStmt *S) { + VisitStmt(S); + + S->setCondition(Record.readSubExpr()); + S->setBody(Record.readSubStmt()); + + S->setWhenLoc(readSourceLocation()); +} + void ASTStmtReader::VisitDoStmt(DoStmt *S) { VisitStmt(S); S->setCond(Record.readSubExpr()); @@ -3009,6 +3018,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /* HasVar=*/Record[ASTStmtReader::NumStmtFields]); break; + case STMT_WHEN: + S = WhenStmt::CreateEmpty(Context); + break; + case STMT_DO: S = new (Context) DoStmt(Empty); break; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index e7f567ff59a8a..9a5b2ba560e90 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -272,6 +272,15 @@ void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) { Code = serialization::STMT_WHILE; } +void ASTStmtWriter::VisitWhenStmt(WhenStmt *S) { + VisitStmt(S); + + Record.AddStmt(S->getCondition()); + Record.AddStmt(S->getBody()); + Record.AddSourceLocation(S->getWhenLoc()); + Code = serialization::STMT_WHEN; +} + void ASTStmtWriter::VisitDoStmt(DoStmt *S) { VisitStmt(S); Record.AddStmt(S->getCond()); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 22eab9f66418d..ed8fd93a2859c 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1865,6 +1865,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::NullStmtClass: case Stmt::SwitchStmtClass: case Stmt::WhileStmtClass: + case Stmt::WhenStmtClass: case Expr::MSDependentExistsStmtClass: llvm_unreachable("Stmt should not be in analyzer evaluation loop"); case Stmt::ImplicitValueInitExprClass: