summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/DeclSpec.cpp
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2018-04-25 02:42:26 +0000
committerFaisal Vali <faisalv@yahoo.com>2018-04-25 02:42:26 +0000
commit936de9d666009ddce7bedc5b073bc06c860d5f5b (patch)
tree440e812f02457e38b03ebed89c36ecfc22a052a3 /clang/lib/Sema/DeclSpec.cpp
parente21278d93805689c5e5d6bb1d52a8d907fd7ba5c (diff)
downloadbcm5719-llvm-936de9d666009ddce7bedc5b073bc06c860d5f5b.tar.gz
bcm5719-llvm-936de9d666009ddce7bedc5b073bc06c860d5f5b.zip
[c++2a] [concepts] Add rudimentary parsing support for template concept declarations
This patch is a tweak of changyu's patch: https://reviews.llvm.org/D40381. It differs in that the recognition of the 'concept' token is moved into the machinery that recognizes declaration-specifiers - this allows us to leverage the attribute handling machinery more seamlessly. See the test file to get a sense of the basic parsing that this patch supports. There is much more work to be done before concepts are usable... Thanks Changyu! llvm-svn: 330794
Diffstat (limited to 'clang/lib/Sema/DeclSpec.cpp')
-rw-r--r--clang/lib/Sema/DeclSpec.cpp66
1 files changed, 65 insertions, 1 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 2fad5a18ba6..5f5d94eee35 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -426,6 +426,7 @@ unsigned DeclSpec::getParsedSpecifiers() const {
return Res;
}
+
template <class T> static bool BadSpecifier(T TNew, T TPrev,
const char *&PrevSpec,
unsigned &DiagID,
@@ -491,7 +492,6 @@ const char *DeclSpec::getSpecifierName(TSS S) {
}
llvm_unreachable("Unknown typespec!");
}
-
const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
const PrintingPolicy &Policy) {
switch (T) {
@@ -969,6 +969,69 @@ bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
return false;
}
+bool DeclSpec::setConceptSpec(const SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID, const PrintingPolicy &PP) {
+ assert(Loc.isValid() && "Loc must be valid, since it is used to identify "
+ "that this function was called before");
+ assert(!ConceptLoc.isValid() &&
+ "how is this called if concept was already encountered and triggered "
+ "ParseConceptDefinition which parses upto the semi-colon");
+
+ PrevSpec = nullptr;
+ if (TypeSpecType != TST_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName(static_cast<TST>(TypeSpecType), PP);
+ ClearTypeSpecType();
+ }
+ if (TypeSpecSign != TSS_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName(static_cast<TSS>(TypeSpecSign));
+ TypeSpecSign = TSS_unspecified;
+ }
+ if (TypeSpecWidth != TSW_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName(static_cast<TSW>(TypeSpecWidth));
+ TypeSpecWidth = TSW_unspecified;
+ }
+ if (StorageClassSpec != SCS_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName(static_cast<SCS>(StorageClassSpec));
+ ClearStorageClassSpecs();
+ }
+ if (ThreadStorageClassSpec != TSCS_unspecified) {
+ PrevSpec =
+ DeclSpec::getSpecifierName(static_cast<TSCS>(ThreadStorageClassSpec));
+ ClearStorageClassSpecs();
+ }
+ if (TypeSpecComplex != TSC_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName(static_cast<TSC>(TypeSpecComplex));
+ TypeSpecComplex = TSC_unspecified;
+ }
+ if (getTypeQualifiers()) {
+ PrevSpec = DeclSpec::getSpecifierName(static_cast<TQ>(TypeQualifiers));
+ ClearTypeQualifiers();
+ }
+ if (isFriendSpecified()) {
+ PrevSpec = "friend";
+ Friend_specified = false;
+ FriendLoc = SourceLocation();
+ }
+ if (isConstexprSpecified()) {
+ PrevSpec = "constexpr";
+ Constexpr_specified = false;
+ ConstexprLoc = SourceLocation();
+ }
+ if (isInlineSpecified()) {
+ PrevSpec = "inline";
+ FS_inlineLoc = SourceLocation();
+ FS_inline_specified = false;
+ }
+
+ if (PrevSpec) {
+ DiagID = diag::err_invalid_decl_spec_combination;
+ }
+ // We set the concept location regardless of whether an error occurred.
+ DeclRep = nullptr;
+ ConceptLoc = Loc;
+ return PrevSpec; // If this is non-null, an error occurred.
+}
+
void DeclSpec::SaveWrittenBuiltinSpecs() {
writtenBS.Sign = getTypeSpecSign();
writtenBS.Width = getTypeSpecWidth();
@@ -1270,6 +1333,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
// TODO: return "auto function" and other bad things based on the real type.
// 'data definition has no type or storage class'?
+
}
bool DeclSpec::isMissingDeclaratorOk() {
OpenPOWER on IntegriCloud