diff options
author | Faisal Vali <faisalv@yahoo.com> | 2018-04-25 02:42:26 +0000 |
---|---|---|
committer | Faisal Vali <faisalv@yahoo.com> | 2018-04-25 02:42:26 +0000 |
commit | 936de9d666009ddce7bedc5b073bc06c860d5f5b (patch) | |
tree | 440e812f02457e38b03ebed89c36ecfc22a052a3 /clang/lib/Sema/DeclSpec.cpp | |
parent | e21278d93805689c5e5d6bb1d52a8d907fd7ba5c (diff) | |
download | bcm5719-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.cpp | 66 |
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() { |