diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 63ca582b009f679e183900d2525aa36eadebf05a..d00a82c91361925d209df05d9742829b1b200e0b 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1949,6 +1949,24 @@ bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs, }; do { + if (getLangOpts().BSC && !Tok.isOneOf(tok::kw_struct, + tok::kw_enum, + tok::kw_union)) { + // if template argument list like or + // we should only parse , ignore the type of constant template + // so we will consume bulltin type 'int' or typedef type 'MyInt' + if (PP.LookAhead(0).is(tok::identifier)) ConsumeToken(); + // if template argument list like + // should consume tokens 'unsigned long int' + int ShouldConsumeCnt = 0; + while (PP.LookAhead(ShouldConsumeCnt).isOneOf(tok::kw_int, tok::kw_long, + tok::kw_short, tok::kw_unsigned, + tok::kw_signed)) + ShouldConsumeCnt++; + if (PP.LookAhead(ShouldConsumeCnt).is(tok::identifier)) { + for (int i = 0; i <= ShouldConsumeCnt; i++) ConsumeToken(); + } + } PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp); ParsedTemplateArgument Arg = ParseTemplateArgument(); SourceLocation EllipsisLoc; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 7254adce1beebb8b261035a06342818f736e6191..301cb2ecdbcb27ff3d843ed9fd1e2570c4daef21 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14452,10 +14452,16 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D, int ParamSize, CurrTL.getAs(); const TemplateSpecializationType* SpecType = SpecTL.getTypePtr(); for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i) { - QualType TemplateArg = SpecType->getArg(i).getAsType(); - TypeSourceInfo *TemplateArgTypeInfo = - Context.getTrivialTypeSourceInfo(TemplateArg, DS.getBeginLoc()); - SpecTL.setArgLocInfo(i, TemplateArgumentLocInfo(TemplateArgTypeInfo)); + TemplateArgument TemplateArg = SpecType->getArg(i); + if (TemplateArg.getKind() == clang::TemplateArgument::Expression) { + Expr *TemplateArgExpr = TemplateArg.getAsExpr(); + SpecTL.setArgLocInfo(i, TemplateArgumentLocInfo(TemplateArgExpr)); + } else if (TemplateArg.getKind() == clang::TemplateArgument::Type){ + QualType TemplateArgType = TemplateArg.getAsType(); + TypeSourceInfo *TemplateArgTypeInfo = + Context.getTrivialTypeSourceInfo(TemplateArgType, DS.getBeginLoc()); + SpecTL.setArgLocInfo(i, TemplateArgumentLocInfo(TemplateArgTypeInfo)); + } } } } diff --git a/clang/test/BSC/Negative/Generic/Constant/Invalid_constant/Invalid_constant.cbs b/clang/test/BSC/Negative/Generic/Constant/Invalid_constant/Invalid_constant.cbs index 5fae063681def2bb29bd31279d007b3260254160..94858e4deca3675a101e00305227eb2ea1ee1136 100644 --- a/clang/test/BSC/Negative/Generic/Constant/Invalid_constant/Invalid_constant.cbs +++ b/clang/test/BSC/Negative/Generic/Constant/Invalid_constant/Invalid_constant.cbs @@ -16,8 +16,7 @@ int foo_3(int a) { // expected-note {{candidate template ignored: return x; } -float foo_4(int a) { /* expected-error {{a non-type template parameter cannot have type 'float' before C++20}} - expected-error {{type-id cannot have a name}} */ +float foo_4(int a) { // expected-error {{a non-type template parameter cannot have type 'float' before C++20}} float x = F; return x; } diff --git a/clang/test/BSC/Positive/Generic/Constant/Constant_member_function/Constant_member_function.cbs b/clang/test/BSC/Positive/Generic/Constant/Constant_member_function/Constant_member_function.cbs new file mode 100644 index 0000000000000000000000000000000000000000..16c5c17046c4e4d933e594d8700ce02dc88dabb1 --- /dev/null +++ b/clang/test/BSC/Positive/Generic/Constant/Constant_member_function/Constant_member_function.cbs @@ -0,0 +1,37 @@ +// RUN: %clang %s -o %t.output +// RUN: %t.output +// expected-no-diagnostics + +#include +struct S1 { + T a[N]; +}; +void struct S1::init(This* this, int b){ + for (int i = 0; i < N; i++) this->a[i] = i + b; +} +void struct S1::dump(struct S1* this){ + for (int i = 0; i < N; i++) printf("%d\n", this->a[i]); +} + +typedef unsigned long long int MyInt; +struct S2 { + T a[N]; +}; +void struct S2::init(This* this, int b){ + for (int i = 0; i < N; i++) this->a[i] = i + b; +} +void struct S2::dump(struct S2* this){ + for (int i = 0; i < N; i++) printf("%d\n", this->a[i]); +} + +int main() { + struct S1 s1; + s1.init(2); + s1.dump(); //print 2, 3, 4, 5, 6 + + struct S2<5, int> s2; + s2.init(4); + s2.dump(); //print 4, 5, 6, 7 ,8 + + return 0; +} diff --git a/clang/test/BSC/Positive/Generic/Constant/Constant_member_function/expected.txt b/clang/test/BSC/Positive/Generic/Constant/Constant_member_function/expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..5293b2de5b46089c9b81d356ede019ab0ff94161 --- /dev/null +++ b/clang/test/BSC/Positive/Generic/Constant/Constant_member_function/expected.txt @@ -0,0 +1,10 @@ +2 +3 +4 +5 +6 +4 +5 +6 +7 +8 diff --git a/clang/test/BSC/Positive/cfg.txt b/clang/test/BSC/Positive/cfg.txt index 3320ad30b3137e5a333ea272451a28b9684075ae..a1b1f03120f69f4aba223b4f2fae9b13e20ca311 100644 --- a/clang/test/BSC/Positive/cfg.txt +++ b/clang/test/BSC/Positive/cfg.txt @@ -205,3 +205,4 @@ BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_9/rewrite_bsc_generi BSC/Positive/Driver/rewrite-bsc/rewrite_static_func/rewrite_static_func.cbs BSC/Positive/Coroutine/Other/async-func-pointer-2/async-func-pointer-2.cbs BSC/Positive/Driver/rewrite-bsc/rewrite_bsc_with_macro/rewrite_bsc_with_macro.cbs +BSC/Positive/Generic/Constant/Constant_member_functcdion/Constant_member_function.cbs \ No newline at end of file