aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h')
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h166
1 files changed, 126 insertions, 40 deletions
diff --git a/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h b/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h
index 2437be497de4..4561cca929c0 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h
@@ -32,6 +32,7 @@
#include "clang/Lex/Token.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/ParsedAttr.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -61,9 +62,18 @@ namespace clang {
/// often used as if it meant "present".
///
/// The actual scope is described by getScopeRep().
+///
+/// If the kind of getScopeRep() is TypeSpec then TemplateParamLists may be empty
+/// or contain the template parameter lists attached to the current declaration.
+/// Consider the following example:
+/// template <class T> void SomeType<T>::some_method() {}
+/// If CXXScopeSpec refers to SomeType<T> then TemplateParamLists will contain
+/// a single element referring to template <class T>.
+
class CXXScopeSpec {
SourceRange Range;
NestedNameSpecifierLocBuilder Builder;
+ ArrayRef<TemplateParameterList *> TemplateParamLists;
public:
SourceRange getRange() const { return Range; }
@@ -73,6 +83,13 @@ public:
SourceLocation getBeginLoc() const { return Range.getBegin(); }
SourceLocation getEndLoc() const { return Range.getEnd(); }
+ void setTemplateParamLists(ArrayRef<TemplateParameterList *> L) {
+ TemplateParamLists = L;
+ }
+ ArrayRef<TemplateParameterList *> getTemplateParamLists() const {
+ return TemplateParamLists;
+ }
+
/// Retrieve the representation of the nested-name-specifier.
NestedNameSpecifier *getScopeRep() const {
return Builder.getRepresentation();
@@ -288,9 +305,13 @@ public:
static const TST TST_typename = clang::TST_typename;
static const TST TST_typeofType = clang::TST_typeofType;
static const TST TST_typeofExpr = clang::TST_typeofExpr;
+ static const TST TST_typeof_unqualType = clang::TST_typeof_unqualType;
+ static const TST TST_typeof_unqualExpr = clang::TST_typeof_unqualExpr;
static const TST TST_decltype = clang::TST_decltype;
static const TST TST_decltype_auto = clang::TST_decltype_auto;
- static const TST TST_underlyingType = clang::TST_underlyingType;
+#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
+ static const TST TST_##Trait = clang::TST_##Trait;
+#include "clang/Basic/TransformTypeTraits.def"
static const TST TST_auto = clang::TST_auto;
static const TST TST_auto_type = clang::TST_auto_type;
static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
@@ -323,6 +344,11 @@ public:
// FIXME: Attributes should be included here.
};
+ enum FriendSpecified : bool {
+ No,
+ Yes,
+ };
+
private:
// storage-class-specifier
/*SCS*/unsigned StorageClassSpec : 3;
@@ -333,7 +359,7 @@ private:
/*TypeSpecifierWidth*/ unsigned TypeSpecWidth : 2;
/*TSC*/unsigned TypeSpecComplex : 2;
/*TSS*/unsigned TypeSpecSign : 2;
- /*TST*/unsigned TypeSpecType : 6;
+ /*TST*/unsigned TypeSpecType : 7;
unsigned TypeAltiVecVector : 1;
unsigned TypeAltiVecPixel : 1;
unsigned TypeAltiVecBool : 1;
@@ -400,11 +426,12 @@ private:
ObjCDeclSpec *ObjCQualifiers;
static bool isTypeRep(TST T) {
- return (T == TST_typename || T == TST_typeofType ||
- T == TST_underlyingType || T == TST_atomic);
+ return T == TST_atomic || T == TST_typename || T == TST_typeofType ||
+ T == TST_typeof_unqualType || isTransformTypeTrait(T);
}
static bool isExprRep(TST T) {
- return (T == TST_typeofExpr || T == TST_decltype || T == TST_bitint);
+ return T == TST_typeofExpr || T == TST_typeof_unqualExpr ||
+ T == TST_decltype || T == TST_bitint;
}
static bool isTemplateIdRep(TST T) {
return (T == TST_auto || T == TST_decltype_auto);
@@ -418,6 +445,14 @@ public:
T == TST_interface || T == TST_union ||
T == TST_class);
}
+ static bool isTransformTypeTrait(TST T) {
+ constexpr std::array<TST, 16> Traits = {
+#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) TST_##Trait,
+#include "clang/Basic/TransformTypeTraits.def"
+ };
+
+ return T >= Traits.front() && T <= Traits.back();
+ }
DeclSpec(AttributeFactory &attrFactory)
: StorageClassSpec(SCS_unspecified),
@@ -516,12 +551,13 @@ public:
SourceLocation getTypeSpecSatLoc() const { return TSSatLoc; }
SourceLocation getTypeSpecTypeNameLoc() const {
- assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename);
+ assert(isDeclRep((TST)TypeSpecType) || isTypeRep((TST)TypeSpecType) ||
+ isExprRep((TST)TypeSpecType));
return TSTNameLoc;
}
SourceRange getTypeofParensRange() const { return TypeofParensRange; }
- void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; }
+ void setTypeArgumentRange(SourceRange range) { TypeofParensRange = range; }
bool hasAutoTypeSpec() const {
return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type ||
@@ -745,7 +781,10 @@ public:
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID);
- bool isFriendSpecified() const { return Friend_specified; }
+ FriendSpecified isFriendSpecified() const {
+ return static_cast<FriendSpecified>(Friend_specified);
+ }
+
SourceLocation getFriendSpecLoc() const { return FriendLoc; }
bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); }
@@ -786,7 +825,7 @@ public:
/// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
/// \endcode
///
- void addAttributes(ParsedAttributesView &AL) {
+ void addAttributes(const ParsedAttributesView &AL) {
Attrs.addAll(AL.begin(), AL.end());
}
@@ -952,10 +991,10 @@ private:
UnqualifiedId(const UnqualifiedId &Other) = delete;
const UnqualifiedId &operator=(const UnqualifiedId &) = delete;
-public:
/// Describes the kind of unqualified-id parsed.
UnqualifiedIdKind Kind;
+public:
struct OFI {
/// The kind of overloaded operator.
OverloadedOperatorKind Operator;
@@ -1342,7 +1381,7 @@ struct DeclaratorChunk {
/// DeclSpec for the function with the qualifier related info.
DeclSpec *MethodQualifiers;
- /// AtttibuteFactory for the MethodQualifiers.
+ /// AttributeFactory for the MethodQualifiers.
AttributeFactory *QualAttrFactory;
union {
@@ -1490,7 +1529,7 @@ struct DeclaratorChunk {
/// prototype. Typically these are tag declarations.
ArrayRef<NamedDecl *> getDeclsInPrototype() const {
assert(ExceptionSpecType == EST_None);
- return llvm::makeArrayRef(DeclsInPrototype, NumExceptionsOrDecls);
+ return llvm::ArrayRef(DeclsInPrototype, NumExceptionsOrDecls);
}
/// Determine whether this function declarator had a
@@ -1737,7 +1776,7 @@ public:
}
ArrayRef<Binding> bindings() const {
- return llvm::makeArrayRef(Bindings, NumBindings);
+ return llvm::ArrayRef(Bindings, NumBindings);
}
bool isSet() const { return LSquareLoc.isValid(); }
@@ -1785,7 +1824,15 @@ enum class DeclaratorContext {
TemplateTypeArg, // Template type argument (in default argument).
AliasDecl, // C++11 alias-declaration.
AliasTemplate, // C++11 alias-declaration template.
- RequiresExpr // C++2a requires-expression.
+ RequiresExpr, // C++2a requires-expression.
+ Association // C11 _Generic selection expression association.
+};
+
+// Describes whether the current context is a context where an implicit
+// typename is allowed (C++2a [temp.res]p5]).
+enum class ImplicitTypenameContext {
+ No,
+ Yes,
};
/// Information about one declarator, including the parsed type
@@ -1850,9 +1897,13 @@ private:
/// Indicates whether this declarator has an initializer.
unsigned HasInitializer : 1;
- /// Attrs - Attributes.
+ /// Attributes attached to the declarator.
ParsedAttributes Attrs;
+ /// Attributes attached to the declaration. See also documentation for the
+ /// corresponding constructor parameter.
+ const ParsedAttributesView &DeclarationAttrs;
+
/// The asm label, if specified.
Expr *AsmLabel;
@@ -1891,16 +1942,41 @@ private:
friend struct DeclaratorChunk;
public:
- Declarator(const DeclSpec &ds, DeclaratorContext C)
- : DS(ds), Range(ds.getSourceRange()), Context(C),
+ /// `DS` and `DeclarationAttrs` must outlive the `Declarator`. In particular,
+ /// take care not to pass temporary objects for these parameters.
+ ///
+ /// `DeclarationAttrs` contains [[]] attributes from the
+ /// attribute-specifier-seq at the beginning of a declaration, which appertain
+ /// to the declared entity itself. Attributes with other syntax (e.g. GNU)
+ /// should not be placed in this attribute list; if they occur at the
+ /// beginning of a declaration, they apply to the `DeclSpec` and should be
+ /// attached to that instead.
+ ///
+ /// Here is an example of an attribute associated with a declaration:
+ ///
+ /// [[deprecated]] int x, y;
+ ///
+ /// This attribute appertains to all of the entities declared in the
+ /// declaration, i.e. `x` and `y` in this case.
+ Declarator(const DeclSpec &DS, const ParsedAttributesView &DeclarationAttrs,
+ DeclaratorContext C)
+ : DS(DS), Range(DS.getSourceRange()), Context(C),
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
GroupingParens(false), FunctionDefinition(static_cast<unsigned>(
FunctionDefinitionKind::Declaration)),
Redeclaration(false), Extension(false), ObjCIvar(false),
ObjCWeakProperty(false), InlineStorageUsed(false),
- HasInitializer(false), Attrs(ds.getAttributePool().getFactory()),
- AsmLabel(nullptr), TrailingRequiresClause(nullptr),
- InventedTemplateParameterList(nullptr) {}
+ HasInitializer(false), Attrs(DS.getAttributePool().getFactory()),
+ DeclarationAttrs(DeclarationAttrs), AsmLabel(nullptr),
+ TrailingRequiresClause(nullptr),
+ InventedTemplateParameterList(nullptr) {
+ assert(llvm::all_of(DeclarationAttrs,
+ [](const ParsedAttr &AL) {
+ return (AL.isStandardAttributeSyntax() ||
+ AL.isRegularKeywordAttribute());
+ }) &&
+ "DeclarationAttrs may only contain [[]] and keyword attributes");
+ }
~Declarator() {
clear();
@@ -2023,6 +2099,7 @@ public:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::RequiresExpr:
+ case DeclaratorContext::Association:
return true;
}
llvm_unreachable("unknown context kind!");
@@ -2062,6 +2139,7 @@ public:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
+ case DeclaratorContext::Association:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2105,6 +2183,7 @@ public:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
+ case DeclaratorContext::Association:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2161,6 +2240,7 @@ public:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::RequiresExpr:
+ case DeclaratorContext::Association:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2383,6 +2463,7 @@ public:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::RequiresExpr:
+ case DeclaratorContext::Association:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2417,6 +2498,7 @@ public:
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::RequiresExpr:
+ case DeclaratorContext::Association:
return false;
case DeclaratorContext::Block:
@@ -2513,19 +2595,24 @@ public:
/// __attribute__((common,deprecated));
///
/// Also extends the range of the declarator.
- void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) {
+ void takeAttributes(ParsedAttributes &attrs) {
Attrs.takeAllFrom(attrs);
- if (!lastLoc.isInvalid())
- SetRangeEnd(lastLoc);
+ if (attrs.Range.getEnd().isValid())
+ SetRangeEnd(attrs.Range.getEnd());
}
const ParsedAttributes &getAttributes() const { return Attrs; }
ParsedAttributes &getAttributes() { return Attrs; }
+ const ParsedAttributesView &getDeclarationAttributes() const {
+ return DeclarationAttrs;
+ }
+
/// hasAttributes - do we contain any attributes?
bool hasAttributes() const {
- if (!getAttributes().empty() || getDeclSpec().hasAttributes())
+ if (!getAttributes().empty() || !getDeclarationAttributes().empty() ||
+ getDeclSpec().hasAttributes())
return true;
for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
if (!getTypeObject(i).getAttrs().empty())
@@ -2533,14 +2620,6 @@ public:
return false;
}
- /// Return a source range list of C++11 attributes associated
- /// with the declarator.
- void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) {
- for (const ParsedAttr &AL : Attrs)
- if (AL.isCXX11Attribute())
- Ranges.push_back(AL.getRange());
- }
-
void setAsmLabel(Expr *E) { AsmLabel = E; }
Expr *getAsmLabel() const { return AsmLabel; }
@@ -2595,6 +2674,8 @@ public:
/// redeclaration time if the decl is static.
bool isStaticMember();
+ bool isExplicitObjectMemberFunction();
+
/// Returns true if this declares a constructor or a destructor.
bool isCtorOrDtor();
@@ -2607,8 +2688,10 @@ public:
struct FieldDeclarator {
Declarator D;
Expr *BitfieldSize;
- explicit FieldDeclarator(const DeclSpec &DS)
- : D(DS, DeclaratorContext::Member), BitfieldSize(nullptr) {}
+ explicit FieldDeclarator(const DeclSpec &DS,
+ const ParsedAttributes &DeclarationAttrs)
+ : D(DS, DeclarationAttrs, DeclaratorContext::Member),
+ BitfieldSize(nullptr) {}
};
/// Represents a C++11 virt-specifier-seq.
@@ -2624,7 +2707,7 @@ public:
VS_Abstract = 16
};
- VirtSpecifiers() : Specifiers(0), LastSpecifier(VS_None) { }
+ VirtSpecifiers() = default;
bool SetSpecifier(Specifier VS, SourceLocation Loc,
const char *&PrevSpec);
@@ -2648,8 +2731,8 @@ public:
Specifier getLastSpecifier() const { return LastSpecifier; }
private:
- unsigned Specifiers;
- Specifier LastSpecifier;
+ unsigned Specifiers = 0;
+ Specifier LastSpecifier = VS_None;
SourceLocation VS_overrideLoc, VS_finalLoc, VS_abstractLoc;
SourceLocation FirstLocation;
@@ -2688,11 +2771,14 @@ struct LambdaIntroducer {
SourceRange Range;
SourceLocation DefaultLoc;
- LambdaCaptureDefault Default;
+ LambdaCaptureDefault Default = LCD_None;
SmallVector<LambdaCapture, 4> Captures;
- LambdaIntroducer()
- : Default(LCD_None) {}
+ LambdaIntroducer() = default;
+
+ bool hasLambdaCapture() const {
+ return Captures.size() > 0 || Default != LCD_None;
+ }
/// Append a capture in a lambda introducer.
void addCapture(LambdaCaptureKind Kind,