summaryrefslogtreecommitdiff
path: root/lib/Sema/DeclSpec.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/Sema/DeclSpec.cpp
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
Notes
Diffstat (limited to 'lib/Sema/DeclSpec.cpp')
-rw-r--r--lib/Sema/DeclSpec.cpp63
1 files changed, 46 insertions, 17 deletions
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index b22eea2b3642a..8b002dac1343e 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -156,14 +156,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
unsigned NumParams,
SourceLocation EllipsisLoc,
SourceLocation RParenLoc,
- unsigned TypeQuals,
bool RefQualifierIsLvalueRef,
SourceLocation RefQualifierLoc,
- SourceLocation ConstQualifierLoc,
- SourceLocation
- VolatileQualifierLoc,
- SourceLocation
- RestrictQualifierLoc,
SourceLocation MutableLoc,
ExceptionSpecificationType
ESpecType,
@@ -178,8 +172,9 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
SourceLocation LocalRangeBegin,
SourceLocation LocalRangeEnd,
Declarator &TheDeclarator,
- TypeResult TrailingReturnType) {
- assert(!(TypeQuals & DeclSpec::TQ_atomic) &&
+ TypeResult TrailingReturnType,
+ DeclSpec *MethodQualifiers) {
+ assert(!(MethodQualifiers && MethodQualifiers->getTypeQualifiers() & DeclSpec::TQ_atomic) &&
"function cannot have _Atomic qualifier");
DeclaratorChunk I;
@@ -193,14 +188,10 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
I.Fun.RParenLoc = RParenLoc.getRawEncoding();
I.Fun.DeleteParams = false;
- I.Fun.TypeQuals = TypeQuals;
I.Fun.NumParams = NumParams;
I.Fun.Params = nullptr;
I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
- I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding();
- I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding();
- I.Fun.RestrictQualifierLoc = RestrictQualifierLoc.getRawEncoding();
I.Fun.MutableLoc = MutableLoc.getRawEncoding();
I.Fun.ExceptionSpecType = ESpecType;
I.Fun.ExceptionSpecLocBeg = ESpecRange.getBegin().getRawEncoding();
@@ -211,8 +202,21 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() ||
TrailingReturnType.isInvalid();
I.Fun.TrailingReturnType = TrailingReturnType.get();
+ I.Fun.MethodQualifiers = nullptr;
+ I.Fun.QualAttrFactory = nullptr;
+
+ if (MethodQualifiers && (MethodQualifiers->getTypeQualifiers() ||
+ MethodQualifiers->getAttributes().size())) {
+ auto &attrs = MethodQualifiers->getAttributes();
+ I.Fun.MethodQualifiers = new DeclSpec(attrs.getPool().getFactory());
+ MethodQualifiers->forEachCVRUQualifier(
+ [&](DeclSpec::TQ TypeQual, StringRef PrintName, SourceLocation SL) {
+ I.Fun.MethodQualifiers->SetTypeQual(TypeQual, SL);
+ });
+ I.Fun.MethodQualifiers->getAttributes().takeAllFrom(attrs);
+ I.Fun.MethodQualifiers->getAttributePool().takeAllFrom(attrs.getPool());
+ }
- assert(I.Fun.TypeQuals == TypeQuals && "bitfield overflow");
assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow");
// new[] a parameter array if needed.
@@ -403,6 +407,24 @@ bool Declarator::isCtorOrDtor() {
(getName().getKind() == UnqualifiedIdKind::IK_DestructorName);
}
+void DeclSpec::forEachCVRUQualifier(
+ llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle) {
+ if (TypeQualifiers & TQ_const)
+ Handle(TQ_const, "const", TQ_constLoc);
+ if (TypeQualifiers & TQ_volatile)
+ Handle(TQ_volatile, "volatile", TQ_volatileLoc);
+ if (TypeQualifiers & TQ_restrict)
+ Handle(TQ_restrict, "restrict", TQ_restrictLoc);
+ if (TypeQualifiers & TQ_unaligned)
+ Handle(TQ_unaligned, "unaligned", TQ_unalignedLoc);
+}
+
+void DeclSpec::forEachQualifier(
+ llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle) {
+ forEachCVRUQualifier(Handle);
+ // FIXME: Add code below to iterate through the attributes and call Handle.
+}
+
bool DeclSpec::hasTagDefinition() const {
if (!TypeSpecOwned)
return false;
@@ -438,7 +460,7 @@ template <class T> static bool BadSpecifier(T TNew, T TPrev,
if (TNew != TPrev)
DiagID = diag::err_invalid_decl_spec_combination;
else
- DiagID = IsExtension ? diag::ext_duplicate_declspec :
+ DiagID = IsExtension ? diag::ext_warn_duplicate_declspec :
diag::warn_duplicate_declspec;
return true;
}
@@ -566,14 +588,16 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
// these storage-class specifiers.
// OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
// specifiers are not supported."
+ // OpenCL C++ v1.0 s2.9 restricts register.
if (S.getLangOpts().OpenCL &&
!S.getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers")) {
switch (SC) {
case SCS_extern:
case SCS_private_extern:
case SCS_static:
- if (S.getLangOpts().OpenCLVersion < 120) {
- DiagID = diag::err_opencl_unknown_type_specifier;
+ if (S.getLangOpts().OpenCLVersion < 120 &&
+ !S.getLangOpts().OpenCLCPlusPlus) {
+ DiagID = diag::err_opencl_unknown_type_specifier;
PrevSpec = getSpecifierName(SC);
return true;
}
@@ -860,6 +884,11 @@ bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
IsExtension = false;
return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
}
+
+ return SetTypeQual(T, Loc);
+}
+
+bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc) {
TypeQualifiers |= T;
switch (T) {
@@ -967,7 +996,7 @@ bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID) {
if (isModulePrivateSpecified()) {
PrevSpec = "__module_private__";
- DiagID = diag::ext_duplicate_declspec;
+ DiagID = diag::ext_warn_duplicate_declspec;
return true;
}