[clang] [lld] [llvm] When (PR #126173)
Abdur Javaid via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 6 19:32:41 PST 2025
https://github.com/abdurj created https://github.com/llvm/llvm-project/pull/126173
None
>From ec2e4574378f4b248277789c4951781a7244be6e Mon Sep 17 00:00:00 2001
From: SongRe <49730299+SongRe at users.noreply.github.com>
Date: Fri, 15 Nov 2024 23:13:45 -0500
Subject: [PATCH 1/2] 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 0e7c6c79001338f..06ad856af2d1755 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 8c39ef3d5a9fa64..6d5dba6c88c5e84 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 1ed5c22361ca683..8bcd6172668b6d2 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 9c089908fdc130e..d39523cd90a009e 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 2c692c999bdff53..deac64dca225982 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 06243f2624876fa..67be14d7ffa539e 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<TST, 16> Traits = {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 7ecb986e4dc2b52..c0779dc309dc05e 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 493123459a5a4db..a2acf9eb52565f4 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 31984453487aefa..b5054f9b6db6799 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 60aab1411a96c58..3b17ab4a44704bc 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 <optional>
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 04c2f1d380bc48b..84de31a063d94fe 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 12d2d3f6060c63f..101468d12b3908e 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 890ca96790acb59..b6ff96fda598b10 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 <anonymous>";
case TagTypeKind::Class:
return "class <anonymous>";
+ case TagTypeKind::Coroutine:
+ return "class <anonymous>";
case TagTypeKind::Union:
return "union <anonymous>";
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 07ac6a3bb4e5b16..c759c321daaa214 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<TagDecl>()) {
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<TagDecl>(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 2ea2a368dd24cfb..6dff76f7dfed943 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 4fac71ba095668a..1f4cb9e71adf2e3 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 a7c70186bc46dee..a3fab18d5c9ffbc 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-->
<DisplayString IncludeView="extra" Condition="TypeSpecType == TST_typeofExpr || TypeSpecType == TST_decltype">
, [{ExprRep}]
</DisplayString>
- <DisplayString IncludeView="extra" Condition="TypeSpecType == TST_enum || TypeSpecType == TST_struct || TypeSpecType == TST_interface || TypeSpecType == TST_union || TypeSpecType == TST_class">
+ <DisplayString IncludeView="extra" Condition="TypeSpecType == TST_enum || TypeSpecType == TST_struct || TypeSpecType == TST_interface || TypeSpecType == TST_union || TypeSpecType == TST_class || TypeSpecType == TST_coroutine">
, [{DeclRep}]
</DisplayString>
<DisplayString IncludeView="extra"></DisplayString>
@@ -868,7 +868,7 @@ For later versions of Visual Studio, no setup is required-->
<Item Name="ExprRep" Condition="TypeSpecType == TST_typeofExpr || TypeSpecType == TST_decltype">
ExprRep
</Item>
- <Item Name="DeclRep" Condition="TypeSpecType == TST_enum || TypeSpecType == TST_struct || TypeSpecType == TST_interface || TypeSpecType == TST_union || TypeSpecType == TST_class">
+ <Item Name="DeclRep" Condition="TypeSpecType == TST_enum || TypeSpecType == TST_struct || TypeSpecType == TST_interface || TypeSpecType == TST_union || TypeSpecType == TST_class || TypeSpecType == TST_coroutine">
DeclRep
</Item>
diff --git a/lld/test/MachO/compact-unwind-generated.test b/lld/test/MachO/compact-unwind-generated.test
index b81236b198c3bd5..34a4e9d820762b5 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 d181a93eb846485..53ee298379cbc3d 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 d3434004414af7066c04d1430932adc28e8987cd Mon Sep 17 00:00:00 2001
From: abdurj <abdur.javaid at gmail.com>
Date: Thu, 6 Feb 2025 22:31:59 -0500
Subject: [PATCH 2/2] 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 76b598a5db2382d..1b45e805d5820cf 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 83fafbabb1d460c..d37ae69774d7298 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<WhenStmt, Stmt *> {
+ 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<SwitchStmt, Stmt *> {
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index 89f5a76eb113120..527a43a820c6624 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -25,6 +25,9 @@ def CaseStmt : StmtNode<SwitchCase>;
def DefaultStmt : StmtNode<SwitchCase>;
def CapturedStmt : StmtNode<Stmt>;
+// uC++ Statements
+def WhenStmt : StmtNode<Stmt>;
+
// Statements that might produce a value (for example, as the last non-null
// statement in a GNU statement-expression).
def ValueStmt : StmtNode<Stmt, 1>;
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index deac64dca225982..5970334265b54b8 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) // <foo>, or "foo" lexed as a header-name
+TOK(header_name) // <foo>, 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 045ee754a242b3c..ef1237e07b3aec1 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -28,28 +28,28 @@
#include <stack>
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<NamedDecl*>(Tok.getAnnotationValue());
+ return static_cast<NamedDecl *>(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<IdentifierInfo*>(Tok.getAnnotationValue());
+ return static_cast<IdentifierInfo *>(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<bool> 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<Decl*, 2> Decls;
+ SmallVector<Decl *, 2> 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<LateParsedAttribute *, 2> {
+ class LateParsedAttrList : public SmallVector<LateParsedAttribute *, 2> {
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<CachedTokens> Toks = nullptr)
- : Param(P), Toks(std::move(Toks)) { }
+ explicit LateParsedDefaultArgument(
+ Decl *P, std::unique_ptr<CachedTokens> 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<LateParsedDeclaration*,2> LateParsedDeclarationsContainer;
+ typedef SmallVector<LateParsedDeclaration *, 2>
+ 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<Decl *> &P,
- SmallVectorImpl<SourceLocation> &PLocs,
- bool WarnOnDeclarations,
- bool ForObjCContainer,
- SourceLocation &LAngleLoc,
- SourceLocation &EndProtoLoc,
- bool consumeLastToken);
+ bool ParseObjCProtocolReferences(
+ SmallVectorImpl<Decl *> &P, SmallVectorImpl<SourceLocation> &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<ParsedType> &typeArgs,
- SourceLocation &typeArgsRAngleLoc,
- SourceLocation &protocolLAngleLoc,
- SmallVectorImpl<Decl *> &protocols,
- SmallVectorImpl<SourceLocation> &protocolLocs,
- SourceLocation &protocolRAngleLoc,
- bool consumeLastToken,
- bool warnOnIncompleteProtocols);
+ ParsedType baseType, SourceLocation &typeArgsLAngleLoc,
+ SmallVectorImpl<ParsedType> &typeArgs, SourceLocation &typeArgsRAngleLoc,
+ SourceLocation &protocolLAngleLoc, SmallVectorImpl<Decl *> &protocols,
+ SmallVectorImpl<SourceLocation> &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<ParsedType> &typeArgs,
- SourceLocation &typeArgsRAngleLoc,
- SourceLocation &protocolLAngleLoc,
- SmallVectorImpl<Decl *> &protocols,
- SmallVectorImpl<SourceLocation> &protocolLocs,
- SourceLocation &protocolRAngleLoc,
- bool consumeLastToken);
+ ParsedType baseType, SourceLocation &typeArgsLAngleLoc,
+ SmallVectorImpl<ParsedType> &typeArgs, SourceLocation &typeArgsRAngleLoc,
+ SourceLocation &protocolLAngleLoc, SmallVectorImpl<Decl *> &protocols,
+ SmallVectorImpl<SourceLocation> &protocolLocs,
+ SourceLocation &protocolRAngleLoc, bool consumeLastToken);
/// Parse a protocol qualifier type such as '<NSCopying>', which is
/// an anachronistic way of writing 'id<NSCopying>'.
@@ -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<LexedMethod*, 8> LateParsedObjCMethodContainer;
+ typedef SmallVector<LexedMethod *, 8> 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<Expr *> &Exprs,
@@ -1949,17 +1913,16 @@ class Parser : public CodeCompletionHandler {
CastExpr // Also allow '(' type-name ')' <anything>
};
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<ParsedType> &DynamicExceptions,
- SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
- ExprResult &NoexceptExpr,
- CachedTokens *&ExceptionSpecTokens);
+ bool Delayed, SourceRange &SpecificationRange,
+ SmallVectorImpl<ParsedType> &DynamicExceptions,
+ SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
+ ExprResult &NoexceptExpr, CachedTokens *&ExceptionSpecTokens);
// EndLoc is filled with the location of the last token of the specification.
- ExceptionSpecificationType ParseDynamicExceptionSpecification(
- SourceRange &SpecificationRange,
- SmallVectorImpl<ParsedType> &Exceptions,
- SmallVectorImpl<SourceRange> &Ranges);
+ ExceptionSpecificationType
+ ParseDynamicExceptionSpecification(SourceRange &SpecificationRange,
+ SmallVectorImpl<ParsedType> &Exceptions,
+ SmallVectorImpl<SourceRange> &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<Expr*> &Exprs,
+ bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr *> &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<Expr*, 12> ExprVector;
+ typedef SmallVector<Expr *, 12> 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<DeclaratorChunk::ParamInfo> &ParamInfo);
+ Declarator &D, SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
void ParseParameterDeclarationClause(
Declarator &D, ParsedAttributes &attrs,
SmallVectorImpl<DeclaratorChunk::ParamInfo> &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<void(CXXScopeSpec &, DeclarationNameInfo)> &
- Callback,
+ const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)>
+ &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<NamedDecl*> &TemplateParams);
+ SmallVectorImpl<NamedDecl *> &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 d6f3508a5243f36..dae5b0538134fea 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 8725d5455ec7351..f123f13d7a9966a 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 fe59d6070b3e811..c3f7aec2de07ec0 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<Stmt *>(NumMandatoryStmtPtr), alignof(WhenStmt));
+ return new (Mem) WhenStmt(Loc, Cond, BodyStmt);
+}
+
+WhenStmt* WhenStmt::CreateEmpty(const ASTContext &Ctx) {
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr), alignof(WhenStmt));
+ return new (Mem) WhenStmt(EmptyShell());
+}
+
// IndirectGotoStmt
LabelDecl *IndirectGotoStmt::getConstantTarget() {
if (auto *E = dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 29f0276d7b7b0ab..b56bba204b65cf9 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<CompoundStmt>(Node->getBody())) {
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 3dfbef1cdb712da..62f532b4ea807b1 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 820bb521ccf850e..44b22e423f66c5c 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -412,6 +412,23 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
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 f6d787a0c88319b..d22d83d20f81cec 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 <optional>
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 bfcdab91dd6f07c..b7ca20c5cc79ea9 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 23720591fbde2f5..b822f6229efba18 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 1f4cb9e71adf2e3..4759b6fbd5eeb8c 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<ParsedAttr *, 2> savedAttrs;
-
- /// A list of attributes to diagnose the uselessness of when the
- /// processing is complete.
- SmallVector<ParsedAttr *, 2> 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<const AttributedType*, const Attr*>;
- SmallVector<TypeAttrPair, 8> AttrsForTypes;
- bool AttrsForTypesSorted = true;
-
- /// MacroQualifiedTypes mapping to macro expansion locations that will be
- /// stored in a MacroQualifiedTypeLoc.
- llvm::DenseMap<const MacroQualifiedType *, SourceLocation> 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<ParsedAttr *, 2> savedAttrs;
- bool isProcessingDeclSpec() const {
- return chunkIndex == declarator.getNumTypeObjects();
- }
+ /// A list of attributes to diagnose the uselessness of when the
+ /// processing is complete.
+ SmallVector<ParsedAttr *, 2> 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<const AttributedType *, const Attr *>;
+ SmallVector<TypeAttrPair, 8> 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<const MacroQualifiedType *, SourceLocation> 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<AttributedType>(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<AttributedType>()) {
- // Attributed type still should be an attributed type after replacement.
- auto *NewAttrTy = cast<AttributedType>(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<AttributedType>(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<AttributedType>()) {
+ // Attributed type still should be an attributed type after replacement.
+ auto *NewAttrTy = cast<AttributedType>(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<DeclSpec&>(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<DeclSpec &>(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<FunctionType>(T.IgnoreParens()) << T
- << getFunctionQualifiersAsString(FPT);
+ << QFK << isa<FunctionType>(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<QualType> paramTypes,
- const FunctionProtoType::ExtProtoInfo &EPI,
- llvm::function_ref<SourceLocation(unsigned)> getParamLoc) {
+static void checkExtParameterInfos(
+ Sema &S, ArrayRef<QualType> paramTypes,
+ const FunctionProtoType::ExtProtoInfo &EPI,
+ llvm::function_ref<SourceLocation(unsigned)> getParamLoc) {
assert(EPI.ExtParameterInfos && "shouldn't get here without param infos");
bool emittedError = false;
@@ -2587,7 +2584,7 @@ static void checkExtParameterInfos(Sema &S, ArrayRef<QualType> 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<QualType> 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<QualType> 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<QualType, TypeSourceInfo *>
@@ -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) {
@@ -3343,9 +3339,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<DeducedTemplateSpecializationType>(Deduced) &&
@@ -3357,8 +3359,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);
@@ -3377,8 +3379,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;
@@ -3499,8 +3501,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();
}
}
@@ -3515,8 +3517,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
@@ -3530,7 +3532,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());
@@ -3538,7 +3540,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);
}
}
}
@@ -3672,7 +3674,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.
@@ -3761,14 +3763,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) {
@@ -3811,33 +3813,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
@@ -4059,7 +4061,7 @@ static void emitNullabilityConsistencyWarning(Sema &S,
S.Diag(PointerLoc, diag::warn_nullability_missing_array);
} else {
S.Diag(PointerLoc, diag::warn_nullability_missing)
- << static_cast<unsigned>(PointerKind);
+ << static_cast<unsigned>(PointerKind);
}
auto FixItLoc = PointerEndLoc.isValid() ? PointerEndLoc : PointerLoc;
@@ -4182,7 +4184,7 @@ static bool IsNoDerefableChunk(const DeclaratorChunk &Chunk) {
Chunk.Kind == DeclaratorChunk::Array);
}
-template<typename AttrT>
+template <typename AttrT>
static AttrT *createSimpleAttr(ASTContext &Ctx, ParsedAttr &AL) {
AL.setUsedAsTypeAttr();
return ::new (Ctx) AttrT(Ctx, AL);
@@ -4219,8 +4221,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;
}
@@ -4261,7 +4262,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<FunctionProtoType>()->getMethodQuals().empty() ||
T->castAs<FunctionProtoType>()->getRefQualifier() != RQ_None);
@@ -4517,8 +4519,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;
@@ -4541,13 +4543,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<int>(complainAboutInferringWithinChunk);
@@ -4711,7 +4714,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Build the type anyway.
}
DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
- Expr *ArraySize = static_cast<Expr*>(ATI.NumElts);
+ Expr *ArraySize = static_cast<Expr *>(ATI.NumElts);
ArraySizeModifier ASM;
// Microsoft property fields can have multiple sizeless array chunks
@@ -4851,8 +4854,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
@@ -4950,7 +4953,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);
}
}
@@ -4991,8 +4995,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) {
@@ -5061,7 +5064,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();
}
}
@@ -5070,7 +5073,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Types shall not be defined in return or parameter types.
TagDecl *Tag = cast<TagDecl>(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
@@ -5135,17 +5138,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<QualType, 16> ParamTys;
ParamTys.reserve(FTI.NumParams);
- SmallVector<FunctionProtoType::ExtParameterInfo, 16>
- ExtParameterInfos(FTI.NumParams);
+ SmallVector<FunctionProtoType::ExtParameterInfo, 16> ExtParameterInfos(
+ FTI.NumParams);
bool HasAnyInterestingExtParameterInfos = false;
for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) {
@@ -5199,7 +5202,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) {
@@ -5225,8 +5229,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
}
if (auto attr = Param->getAttr<ParameterABIAttr>()) {
- ExtParameterInfos[i] =
- ExtParameterInfos[i].withABI(attr->getABI());
+ ExtParameterInfos[i] = ExtParameterInfos[i].withABI(attr->getABI());
HasAnyInterestingExtParameterInfos = true;
}
@@ -5245,8 +5248,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<QualType, 4> Exceptions;
@@ -5268,13 +5272,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.
@@ -5358,9 +5359,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);
}
@@ -5547,9 +5548,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();
@@ -5617,8 +5618,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,
@@ -5638,9 +5639,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:
@@ -5696,8 +5696,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) {
@@ -5707,9 +5706,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();
@@ -5720,11 +5720,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;
@@ -5863,406 +5872,399 @@ static void fillAtomicQualLoc(AtomicTypeLoc ATL, const DeclaratorChunk &Chunk) {
}
namespace {
- class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
- 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<ElaboratedType>()) {
- ElaboratedTypeLoc ElabTL = OldTL.castAs<ElaboratedTypeLoc>();
- TemplateSpecializationTypeLoc NamedTL = ElabTL.getNamedTypeLoc()
- .castAs<TemplateSpecializationTypeLoc>();
- TL.copy(NamedTL);
- } else {
- TL.copy(OldTL.castAs<TemplateSpecializationTypeLoc>());
- assert(TL.getRAngleLoc() == OldTL.castAs<TemplateSpecializationTypeLoc>().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<TypeSpecLocFiller> {
+ 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<ElaboratedType>()) {
+ ElaboratedTypeLoc ElabTL = OldTL.castAs<ElaboratedTypeLoc>();
+ TemplateSpecializationTypeLoc NamedTL =
+ ElabTL.getNamedTypeLoc().castAs<TemplateSpecializationTypeLoc>();
+ TL.copy(NamedTL);
+ } else {
+ TL.copy(OldTL.castAs<TemplateSpecializationTypeLoc>());
+ assert(TL.getRAngleLoc() ==
+ OldTL.castAs<TemplateSpecializationTypeLoc>().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<ElaboratedTypeLoc>()) {
+ 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<DependentNameTypeLoc>());
+ }
+ void VisitDependentTemplateSpecializationTypeLoc(
+ DependentTemplateSpecializationTypeLoc TL) {
+ assert(DS.getTypeSpecType() == TST_typename);
+ TypeSourceInfo *TInfo = nullptr;
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
+ assert(TInfo);
+ TL.copy(
+ TInfo->getTypeLoc().castAs<DependentTemplateSpecializationTypeLoc>());
+ }
+ 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<NamedDecl>(USD);
+ else
+ FoundDecl = cast_if_present<NamedDecl>(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<ElaboratedTypeLoc>()) {
- 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<DependentNameTypeLoc>());
+ 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<DependentTemplateSpecializationTypeLoc>());
- }
- 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<NamedDecl>(USD);
- else
- FoundDecl = cast_if_present<NamedDecl>(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<DeclaratorLocFiller> {
+ ASTContext &Context;
+ TypeProcessingState &State;
+ const DeclaratorChunk &Chunk;
- class DeclaratorLocFiller : public TypeLocVisitor<DeclaratorLocFiller> {
- 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<DependentNameType>(ClsTy) && "Unexpected TypeLoc");
- {
- DependentNameTypeLoc DNTLoc = ClsTL.castAs<DependentNameTypeLoc>();
- 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<ElaboratedType>(ClsTy)) {
- ElaboratedTypeLoc ETLoc = ClsTL.castAs<ElaboratedTypeLoc>();
- 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<DependentNameType>(ClsTy) && "Unexpected TypeLoc");
+ {
+ DependentNameTypeLoc DNTLoc = ClsTL.castAs<DependentNameTypeLoc>();
+ 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<Expr*>(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<ParmVarDecl>(FTI.Params[i].Param);
- TL.setParam(tpi++, Param);
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ if (isa<ElaboratedType>(ClsTy)) {
+ ElaboratedTypeLoc ETLoc = ClsTL.castAs<ElaboratedTypeLoc>();
+ 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<Expr *>(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<ParmVarDecl>(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
@@ -6290,8 +6292,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();
@@ -6388,8 +6390,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) {
@@ -6564,8 +6566,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;
}
@@ -6663,8 +6665,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;
}
@@ -6687,8 +6689,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;
}
@@ -6696,12 +6697,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;
}
@@ -6727,12 +6727,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,
@@ -6749,8 +6755,8 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
if (!S.getLangOpts().ObjCAutoRefCount &&
lifetime == Qualifiers::OCL_ExplicitNone) {
type = state.getAttributedType(
- createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context, attr),
- type, type);
+ createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context, attr), type,
+ type);
return true;
}
@@ -6766,26 +6772,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);
@@ -6798,7 +6803,7 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
// objc_arc_weak_reference_unavailable
if (lifetime == Qualifiers::OCL_Weak) {
if (const ObjCObjectPointerType *ObjT =
- type->getAs<ObjCObjectPointerType>()) {
+ type->getAs<ObjCObjectPointerType>()) {
if (ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl()) {
if (Class->isArcWeakrefUnavailable()) {
S.Diag(AttrLoc, diag::err_arc_unsupported_weak_class);
@@ -6821,8 +6826,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;
@@ -6841,8 +6845,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;
}
@@ -6871,182 +6875,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<unsigned char /*WrapKind*/, 8> Stack;
-
- FunctionTypeUnwrapper(Sema &S, QualType T) : Original(T) {
- while (true) {
- const Type *Ty = T.getTypePtr();
- if (isa<FunctionType>(Ty)) {
- Fn = cast<FunctionType>(Ty);
- return;
- } else if (isa<ParenType>(Ty)) {
- T = cast<ParenType>(Ty)->getInnerType();
- Stack.push_back(Parens);
- } else if (isa<ConstantArrayType>(Ty) || isa<VariableArrayType>(Ty) ||
- isa<IncompleteArrayType>(Ty)) {
- T = cast<ArrayType>(Ty)->getElementType();
- Stack.push_back(Array);
- } else if (isa<PointerType>(Ty)) {
- T = cast<PointerType>(Ty)->getPointeeType();
- Stack.push_back(Pointer);
- } else if (isa<BlockPointerType>(Ty)) {
- T = cast<BlockPointerType>(Ty)->getPointeeType();
- Stack.push_back(BlockPointer);
- } else if (isa<MemberPointerType>(Ty)) {
- T = cast<MemberPointerType>(Ty)->getPointeeType();
- Stack.push_back(MemberPointer);
- } else if (isa<ReferenceType>(Ty)) {
- T = cast<ReferenceType>(Ty)->getPointeeType();
- Stack.push_back(Reference);
- } else if (isa<AttributedType>(Ty)) {
- T = cast<AttributedType>(Ty)->getEquivalentType();
- Stack.push_back(Attributed);
- } else if (isa<MacroQualifiedType>(Ty)) {
- T = cast<MacroQualifiedType>(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<unsigned char /*WrapKind*/, 8> Stack;
+
+ FunctionTypeUnwrapper(Sema &S, QualType T) : Original(T) {
+ while (true) {
+ const Type *Ty = T.getTypePtr();
+ if (isa<FunctionType>(Ty)) {
+ Fn = cast<FunctionType>(Ty);
+ return;
+ } else if (isa<ParenType>(Ty)) {
+ T = cast<ParenType>(Ty)->getInnerType();
+ Stack.push_back(Parens);
+ } else if (isa<ConstantArrayType>(Ty) || isa<VariableArrayType>(Ty) ||
+ isa<IncompleteArrayType>(Ty)) {
+ T = cast<ArrayType>(Ty)->getElementType();
+ Stack.push_back(Array);
+ } else if (isa<PointerType>(Ty)) {
+ T = cast<PointerType>(Ty)->getPointeeType();
+ Stack.push_back(Pointer);
+ } else if (isa<BlockPointerType>(Ty)) {
+ T = cast<BlockPointerType>(Ty)->getPointeeType();
+ Stack.push_back(BlockPointer);
+ } else if (isa<MemberPointerType>(Ty)) {
+ T = cast<MemberPointerType>(Ty)->getPointeeType();
+ Stack.push_back(MemberPointer);
+ } else if (isa<ReferenceType>(Ty)) {
+ T = cast<ReferenceType>(Ty)->getPointeeType();
+ Stack.push_back(Reference);
+ } else if (isa<AttributedType>(Ty)) {
+ T = cast<AttributedType>(Ty)->getEquivalentType();
+ Stack.push_back(Attributed);
+ } else if (isa<MacroQualifiedType>(Ty)) {
+ T = cast<MacroQualifiedType>(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<WrapKind>(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<AttributedType>(Old)->getEquivalentType(), I);
+ switch (static_cast<WrapKind>(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<ParenType>(Old)->getInnerType(), I);
- return C.getParenType(New);
- }
+ case Attributed:
+ return wrap(C, cast<AttributedType>(Old)->getEquivalentType(), I);
- case MacroQualified:
- return wrap(C, cast<MacroQualifiedType>(Old)->getUnderlyingType(), I);
+ case Parens: {
+ QualType New = wrap(C, cast<ParenType>(Old)->getInnerType(), I);
+ return C.getParenType(New);
+ }
- case Array: {
- if (const auto *CAT = dyn_cast<ConstantArrayType>(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<MacroQualifiedType>(Old)->getUnderlyingType(), I);
- if (const auto *VAT = dyn_cast<VariableArrayType>(Old)) {
- QualType New = wrap(C, VAT->getElementType(), I);
- return C.getVariableArrayType(
- New, VAT->getSizeExpr(), VAT->getSizeModifier(),
- VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange());
- }
-
- const auto *IAT = cast<IncompleteArrayType>(Old);
- QualType New = wrap(C, IAT->getElementType(), I);
- return C.getIncompleteArrayType(New, IAT->getSizeModifier(),
- IAT->getIndexTypeCVRQualifiers());
+ case Array: {
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(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<PointerType>(Old)->getPointeeType(), I);
- return C.getPointerType(New);
+ if (const auto *VAT = dyn_cast<VariableArrayType>(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<BlockPointerType>(Old)->getPointeeType(),I);
- return C.getBlockPointerType(New);
- }
+ const auto *IAT = cast<IncompleteArrayType>(Old);
+ QualType New = wrap(C, IAT->getElementType(), I);
+ return C.getIncompleteArrayType(New, IAT->getSizeModifier(),
+ IAT->getIndexTypeCVRQualifiers());
+ }
- case MemberPointer: {
- const MemberPointerType *OldMPT = cast<MemberPointerType>(Old);
- QualType New = wrap(C, OldMPT->getPointeeType(), I);
- return C.getMemberPointerType(New, OldMPT->getClass());
- }
+ case Pointer: {
+ QualType New = wrap(C, cast<PointerType>(Old)->getPointeeType(), I);
+ return C.getPointerType(New);
+ }
- case Reference: {
- const ReferenceType *OldRef = cast<ReferenceType>(Old);
- QualType New = wrap(C, OldRef->getPointeeType(), I);
- if (isa<LValueReferenceType>(OldRef))
- return C.getLValueReferenceType(New, OldRef->isSpelledAsLValue());
- else
- return C.getRValueReferenceType(New);
- }
- }
+ case BlockPointer: {
+ QualType New = wrap(C, cast<BlockPointerType>(Old)->getPointeeType(), I);
+ return C.getBlockPointerType(New);
+ }
- llvm_unreachable("unknown wrapping kind");
+ case MemberPointer: {
+ const MemberPointerType *OldMPT = cast<MemberPointerType>(Old);
+ QualType New = wrap(C, OldMPT->getPointeeType(), I);
+ return C.getMemberPointerType(New, OldMPT->getClass());
}
- };
+
+ case Reference: {
+ const ReferenceType *OldRef = cast<ReferenceType>(Old);
+ QualType New = wrap(C, OldRef->getPointeeType(), I);
+ if (isa<LValueReferenceType>(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<Ptr32Attr>(S.Context, PAttr);
break;
@@ -7411,14 +7419,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<ObjCObjectPointerType>();
- const ObjCObjectType *objType = ptrType ? ptrType->getObjectType()
- : type->getAs<ObjCObjectType>();
+ const ObjCObjectType *objType =
+ ptrType ? ptrType->getObjectType() : type->getAs<ObjCObjectType>();
// 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;
}
@@ -7475,18 +7482,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<unsigned>(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<unsigned>(pointerKind);
// FIXME: MemberPointer chunks don't carry the location of the *.
if (chunk.Kind != DeclaratorChunk::MemberPointer) {
@@ -7505,7 +7512,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:
@@ -7519,9 +7526,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);
}
@@ -7817,7 +7824,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())
@@ -7831,13 +7839,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<NSReturnsRetainedAttr>(S.Context, attr),
- origType, type);
+ createSimpleAttr<NSReturnsRetainedAttr>(S.Context, attr), origType,
+ type);
return true;
}
@@ -7871,7 +7880,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;
}
@@ -7896,8 +7905,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;
}
@@ -7923,8 +7931,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;
}
@@ -8027,7 +8036,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;
@@ -8092,7 +8102,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;
@@ -8116,8 +8126,8 @@ void Sema::adjustMemberFunctionCC(QualType &T, bool HasThisPointer,
bool IsCtorOrDtor, SourceLocation Loc) {
FunctionTypeUnwrapper Unwrapped(*this, T);
const FunctionType *FT = Unwrapped.get();
- bool IsVariadic = (isa<FunctionProtoType>(FT) &&
- cast<FunctionProtoType>(FT)->isVariadic());
+ bool IsVariadic =
+ (isa<FunctionProtoType>(FT) && cast<FunctionProtoType>(FT)->isVariadic());
CallingConv CurCC = FT->getCallConv();
CallingConv ToCC =
Context.getDefaultCallingConvention(IsVariadic, HasThisPointer);
@@ -8134,7 +8144,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
@@ -8165,8 +8175,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;
}
@@ -8185,8 +8195,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;
}
@@ -8501,14 +8511,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<TypedefType>()) {
+ if (const TypedefType *TypedefTy = CurType->getAs<TypedefType>()) {
QualType BaseTy = TypedefTy->desugar();
std::string PrevAccessQual;
@@ -8520,14 +8531,14 @@ static void HandleOpenCLAccessAttr(QualType &CurType, const ParsedAttr &Attr,
} else {
PrevAccessQual = "read_only";
}
- } else if (const BuiltinType* ImgType = BaseTy->getAs<BuiltinType>()) {
+ } else if (const BuiltinType *ImgType = BaseTy->getAs<BuiltinType>()) {
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.");
}
@@ -8538,14 +8549,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<PipeType>()->getElementType();
@@ -8604,8 +8616,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<LifetimeBoundAttr>(State.getSema().Context, Attr),
@@ -8833,7 +8844,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
@@ -8881,8 +8891,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]];
@@ -9071,9 +9081,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);
}
@@ -9302,9 +9311,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())
@@ -9323,7 +9332,7 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
// an instantiated class template specialization).
// FIXME: Can this ever happen?
} else if (auto *ClassTemplateSpec =
- dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
+ dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
runWithSufficientStackSpace(Loc, [&] {
Diagnosed = InstantiateClassTemplateSpecialization(
@@ -9375,10 +9384,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())
@@ -9411,7 +9420,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!");
}
}
@@ -9454,7 +9464,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();
@@ -9473,8 +9483,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 1465bba87724b9a..11d4dd2951c0738 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<Derived>::TransformWhileStmt(WhileStmt *S) {
Cond, S->getRParenLoc(), Body.get());
}
+template <typename Derived>
+StmtResult TreeTransform<Derived>::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<typename Derived>
StmtResult
TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index c39a1950a6cf245..e907a6e7e2a40cc 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 e7f567ff59a8adf..9a5b2ba560e9017 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 22eab9f66418d4d..ed8fd93a2859c40 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:
More information about the cfe-commits
mailing list