[clang] 5bdd5d0 - Fix PR#62594 : static lambda call operator is not convertible to function pointer on win32

2023-09-16 Thread faisal vali via cfe-commits

Author: faisal vali
Date: 2023-09-16T13:29:59-05:00
New Revision: 5bdd5d064d5171b2d5ff6268528cfffd2f86b8ea

URL: 
https://github.com/llvm/llvm-project/commit/5bdd5d064d5171b2d5ff6268528cfffd2f86b8ea
DIFF: 
https://github.com/llvm/llvm-project/commit/5bdd5d064d5171b2d5ff6268528cfffd2f86b8ea.diff

LOG: Fix PR#62594 : static lambda call operator is not convertible to function 
pointer on win32

See issue https://github.com/llvm/llvm-project/issues/62594

This code does not work on win32:

  auto lstatic = []()  static  { return 0;  };
  int (*f2)(void) = lstatic;

Since a calling convention such as CC_X86ThisCall can rightly interfere with 
the implicit pointer to function conversion if erroneously marked on a static 
function, the fix entails checking the 'static' specifier on the lambda 
declarator prior to assigning it a calling convention of an non-static member 
(which pre-c++23 made sense).

Added: 
clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaType.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d558705f16ca3be..e9bfefd40bbbf82 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -283,6 +283,10 @@ Bug Fixes to C++ Support
 - Clang now properly handles out of line template specializations when there is
   a non-template inner-class between the function and the class template.
   (`#65810 `_)
+  
+- Clang now properly converts static lambda call operator to function 
+  pointer on win32.
+  (`#62594 `_)  
 
 Bug Fixes to AST Handling
 ^

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index ffd29446b4f2edd..d13a5564e9ad64c 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -4095,8 +4095,9 @@ static CallingConv getCCForDeclaratorChunk(
   D.getTypeObject(I).Kind == DeclaratorChunk::MemberPointer;
 } else if (D.getContext() == DeclaratorContext::LambdaExpr) {
   // This can only be a call operator for a lambda, which is an instance
-  // method.
-  IsCXXInstanceMethod = true;
+  // method, unless explicitly specified as 'static'.
+  IsCXXInstanceMethod =
+  D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static;
 } else {
   // We're the innermost decl chunk, so must be a function declarator.
   assert(D.isFunctionDeclarator());

diff  --git a/clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp 
b/clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp
new file mode 100644
index 000..fab76ffc423a3b2
--- /dev/null
+++ b/clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
+
+
+namespace ns1 {
+  auto lstatic = []() static { return 3; }; 
+  int (*f2)(void) = lstatic;   
+
+}
+
+namespace ns1_1 {
+  
+  auto lstatic = []() static consteval  //expected-error{{cannot take address 
of consteval call}} \
+  expected-note {{declared here}} 
+  { return 3; };   
+  
+  // FIXME: the above error should indicate that it was triggered below.
+  int (*f2)(void) = lstatic;   
+
+}
+
+
+namespace ns2 {
+  auto lstatic = []() static { return 3; }; 
+  constexpr int (*f2)(void) = lstatic;  
+  static_assert(lstatic() == f2());
+}
+
+namespace ns3 {
+  void main() {
+static int x = 10;
+auto L = []() static { return x; };
+  }
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D92733: Fix PR25627 - false positive diagnostics involving implicit-captures in dependent lambda expressions.

2023-01-13 Thread Faisal Vali via cfe-commits
I'll try and look into it this weekend and have some sort of updated news
for you by monday?
Faisal Vali



On Thu, Jan 12, 2023 at 10:40 PM Shafik Yaghmour via Phabricator <
revi...@reviews.llvm.org> wrote:

> shafik added a comment.
>
> Is this PR still workable or does it need a major rework and should be
> abandoned?
>
>
> Repository:
>   rG LLVM Github Monorepo
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D92733/new/
>
> https://reviews.llvm.org/D92733
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 9930d4d - [NFC, Refactor] Modernize enum FunctionDefinitionKind (DeclSpech.h) into a scoped enum

2020-11-21 Thread Faisal Vali via cfe-commits

Author: Faisal Vali
Date: 2020-11-21T09:49:52-06:00
New Revision: 9930d4dff31a130890f21a64f43d530a83ae3d0a

URL: 
https://github.com/llvm/llvm-project/commit/9930d4dff31a130890f21a64f43d530a83ae3d0a
DIFF: 
https://github.com/llvm/llvm-project/commit/9930d4dff31a130890f21a64f43d530a83ae3d0a.diff

LOG: [NFC, Refactor] Modernize enum FunctionDefinitionKind (DeclSpech.h) into a 
scoped enum

Reviewed by aaron.ballman, rsmith, wchilders
Highlights of review:
- avoid specifying an underlying type (unless such an enum is stored (or part 
of an abi?))
- avoid using enums as bit-fields, preferring unsigned bit-fields that we 
static_cast enumerators to. (MS's abi laysout enum bit-fields differently).
- clang-format, clang-format, clang-format.

https://reviews.llvm.org/D91035

Thank you!

Added: 


Modified: 
clang/include/clang/Sema/DeclSpec.h
clang/lib/Parse/ParseCXXInlineMethods.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Parse/ParseExpr.cpp
clang/lib/Parse/Parser.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/SemaType.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index d2acafc2e4b3..afcbbaa5cfa7 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1748,11 +1748,11 @@ class DecompositionDeclarator {
 
 /// Described the kind of function definition (if any) provided for
 /// a function.
-enum FunctionDefinitionKind {
-  FDK_Declaration,
-  FDK_Definition,
-  FDK_Defaulted,
-  FDK_Deleted
+enum class FunctionDefinitionKind {
+  Declaration,
+  Definition,
+  Defaulted,
+  Deleted
 };
 
 enum class DeclaratorContext {
@@ -1888,7 +1888,8 @@ class Declarator {
   Declarator(const DeclSpec , DeclaratorContext C)
   : DS(ds), Range(ds.getSourceRange()), Context(C),
 InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
-GroupingParens(false), FunctionDefinition(FDK_Declaration),
+GroupingParens(false), FunctionDefinition(static_cast(
+   FunctionDefinitionKind::Declaration)),
 Redeclaration(false), Extension(false), ObjCIvar(false),
 ObjCWeakProperty(false), InlineStorageUsed(false),
 Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),
@@ -2562,11 +2563,11 @@ class Declarator {
   void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; }
 
   void setFunctionDefinitionKind(FunctionDefinitionKind Val) {
-FunctionDefinition = Val;
+FunctionDefinition = static_cast(Val);
   }
 
   bool isFunctionDefinition() const {
-return getFunctionDefinitionKind() != FDK_Declaration;
+return getFunctionDefinitionKind() != FunctionDefinitionKind::Declaration;
   }
 
   FunctionDefinitionKind getFunctionDefinitionKind() const {

diff  --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp 
b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 12941f214cbc..b0335905b6f8 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -108,7 +108,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
   // or if we are about to parse function member template then consume
   // the tokens and store them for parsing at the end of the translation unit.
   if (getLangOpts().DelayedTemplateParsing &&
-  D.getFunctionDefinitionKind() == FDK_Definition &&
+  D.getFunctionDefinitionKind() == FunctionDefinitionKind::Definition &&
   !D.getDeclSpec().hasConstexprSpecifier() &&
   !(FnD && FnD->getAsFunction() &&
 FnD->getAsFunction()->getReturnType()->getContainedAutoType()) &&

diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp 
b/clang/lib/Parse/ParseDeclCXX.cpp
index 0a810fc393a6..9525c0222b9f 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1045,8 +1045,16 @@ void Parser::AnnotateExistingDecltypeSpecifier(const 
DeclSpec& DS,
SourceLocation StartLoc,
SourceLocation EndLoc) {
   // make sure we have a token we can turn into an annotation token
-  if (PP.isBacktrackEnabled())
+  if (PP.isBacktrackEnabled()) {
 PP.RevertCachedTokens(1);
+if (DS.getTypeSpecType() == TST_error) {
+  // We encountered an error in parsing 'decltype(...)' so lets annotate 
all
+  // the tokens in the backtracking cache - that we likely had to skip over
+  // to get to a token that allows us to resume parsing, such as a
+  // semi-colon.
+  EndLoc = PP.getLastCachedTokenLocation();
+}
+  }
   else
 PP.EnterToken(Tok, /*IsReinject*/true);
 
@@ -2707,23 +2715,23 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier 
AS,
 if (getLangOpts().MicrosoftExt && DeclaratorInfo.isDeclarationOfFunction())
   TryConsumePureSpecifier(/*AllowDefinition*/ true);
 
-FunctionDefinitionKind 

Re: [PATCH] D91035: [NFC, Refactor] Convert FunctionDefinitionKind from DeclSpech.h to a scoped enum

2020-11-14 Thread Faisal Vali via cfe-commits
yay!

Thanks Thorsten - if no one else does it - i'll try and commit this for you
later today :)

Faisal Vali



On Sat, Nov 14, 2020 at 11:08 AM Thorsten via Phabricator <
revi...@reviews.llvm.org> wrote:

> tschuett added a comment.
>
> I started with specifiers.h here: https://reviews.llvm.org/D91409, but it
> is not yet committed.
>
>
> Repository:
>   rG LLVM Github Monorepo
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D91035/new/
>
> https://reviews.llvm.org/D91035
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] e4d2793 - [NFC, Refactor] Rename the (scoped) enum DeclaratorContext's enumerators to remove duplication

2020-11-10 Thread Faisal Vali via cfe-commits

Author: Faisal Vali
Date: 2020-11-10T23:40:12-06:00
New Revision: e4d27932a59fb61aaba3ff7a3ccd1b5bc9215fb9

URL: 
https://github.com/llvm/llvm-project/commit/e4d27932a59fb61aaba3ff7a3ccd1b5bc9215fb9
DIFF: 
https://github.com/llvm/llvm-project/commit/e4d27932a59fb61aaba3ff7a3ccd1b5bc9215fb9.diff

LOG: [NFC, Refactor] Rename the (scoped) enum DeclaratorContext's enumerators 
to remove duplication

Since these are scoped enumerators, they have to be prefixed by 
DeclaratorContext, so lets remove Context from the name, and return some 
characters to the multiverse.

Patch was reviewed here: https://reviews.llvm.org/D91011

Thank you to aaron, bruno, wyatt and barry for indulging me.

Added: 


Modified: 
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/DeclSpec.h
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Parse/ParseExpr.cpp
clang/lib/Parse/ParseExprCXX.cpp
clang/lib/Parse/ParseObjc.cpp
clang/lib/Parse/ParseOpenMP.cpp
clang/lib/Parse/ParseStmt.cpp
clang/lib/Parse/ParseTemplate.cpp
clang/lib/Parse/Parser.cpp
clang/lib/Sema/DeclSpec.cpp
clang/lib/Sema/SemaCodeComplete.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaDeclObjC.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaType.cpp

Removed: 




diff  --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 02b73b311b70..20dba70d8509 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2579,12 +2579,11 @@ class Parser : public CodeCompletionHandler {
   bool TrySkipAttributes();
 
 public:
-  TypeResult ParseTypeName(SourceRange *Range = nullptr,
-   DeclaratorContext Context
- = DeclaratorContext::TypeNameContext,
-   AccessSpecifier AS = AS_none,
-   Decl **OwnedType = nullptr,
-   ParsedAttributes *Attrs = nullptr);
+  TypeResult
+  ParseTypeName(SourceRange *Range = nullptr,
+DeclaratorContext Context = DeclaratorContext::TypeName,
+AccessSpecifier AS = AS_none, Decl **OwnedType = nullptr,
+ParsedAttributes *Attrs = nullptr);
 
 private:
   void ParseBlockId(SourceLocation CaretLoc);

diff  --git a/clang/include/clang/Sema/DeclSpec.h 
b/clang/include/clang/Sema/DeclSpec.h
index abbefc9d285e..0598d0d61b15 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1761,36 +1761,35 @@ enum FunctionDefinitionKind {
 };
 
 enum class DeclaratorContext {
-FileContext, // File scope declaration.
-PrototypeContext,// Within a function prototype.
-ObjCResultContext,   // An ObjC method result type.
-ObjCParameterContext,// An ObjC method parameter type.
-KNRTypeListContext,  // K type definition list for formals.
-TypeNameContext, // Abstract declarator for types.
-FunctionalCastContext, // Type in a C++ functional cast expression.
-MemberContext,   // Struct/Union field.
-BlockContext,// Declaration within a block in a function.
-ForContext,  // Declaration within first part of a for loop.
-InitStmtContext, // Declaration within optional init stmt of if/switch.
-ConditionContext,// Condition declaration in a C++ if/switch/while/for.
-TemplateParamContext,// Within a template parameter list.
-CXXNewContext,   // C++ new-expression.
-CXXCatchContext, // C++ catch exception-declaration
-ObjCCatchContext,// Objective-C catch exception-declaration
-BlockLiteralContext, // Block literal declarator.
-LambdaExprContext,   // Lambda-expression declarator.
-LambdaExprParameterContext, // Lambda-expression parameter declarator.
-ConversionIdContext, // C++ conversion-type-id.
-TrailingReturnContext, // C++11 trailing-type-specifier.
-TrailingReturnVarContext, // C++11 trailing-type-specifier for variable.
-TemplateArgContext,  // Any template argument (in template argument list).
-TemplateTypeArgContext, // Template type argument (in default argument).
-AliasDeclContext,// C++11 alias-declaration.
-AliasTemplateContext, // C++11 alias-declaration template.
-RequiresExprContext   // C++2a requires-expression.
+  File,// File scope declaration.
+  Prototype,   // Within a function prototype.
+  ObjCResult,  // An ObjC method result type.
+  ObjCParameter,   // An ObjC method parameter type.
+  KNRTypeList, // K type definition list for formals.
+  TypeName,// Abstract declarator for types.
+  FunctionalCast,  // Type in a C++ functional cast expression.
+  Member,  // Struct/Union field.
+  Block,   // Declaration within a 

[clang] accd9af - Revert "[nfc] test commit"

2020-05-16 Thread faisal vali via cfe-commits

Author: faisal vali
Date: 2020-05-16T15:12:04-05:00
New Revision: accd9af838b071ff6e8ba4ff3c99a2542cd0ce25

URL: 
https://github.com/llvm/llvm-project/commit/accd9af838b071ff6e8ba4ff3c99a2542cd0ce25
DIFF: 
https://github.com/llvm/llvm-project/commit/accd9af838b071ff6e8ba4ff3c99a2542cd0ce25.diff

LOG: Revert "[nfc] test commit"

This reverts commit 0ee46e857d81ea815e5b11d266c0c118a2c2e714.

Added: 


Modified: 
clang/README.txt

Removed: 




diff  --git a/clang/README.txt b/clang/README.txt
index 5f50e152f9f1..91527b094856 100644
--- a/clang/README.txt
+++ b/clang/README.txt
@@ -24,5 +24,3 @@ on the Clang development mailing list:
 
 If you find a bug in Clang, please file it in the LLVM bug tracker:
   http://llvm.org/bugs/
-
-



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 0ee46e8 - [nfc] test commit

2020-05-16 Thread faisal vali via cfe-commits

Author: faisal vali
Date: 2020-05-16T15:08:30-05:00
New Revision: 0ee46e857d81ea815e5b11d266c0c118a2c2e714

URL: 
https://github.com/llvm/llvm-project/commit/0ee46e857d81ea815e5b11d266c0c118a2c2e714
DIFF: 
https://github.com/llvm/llvm-project/commit/0ee46e857d81ea815e5b11d266c0c118a2c2e714.diff

LOG: [nfc] test commit

Added: 


Modified: 
clang/README.txt

Removed: 




diff  --git a/clang/README.txt b/clang/README.txt
index 91527b094856..5f50e152f9f1 100644
--- a/clang/README.txt
+++ b/clang/README.txt
@@ -24,3 +24,5 @@ on the Clang development mailing list:
 
 If you find a bug in Clang, please file it in the LLVM bug tracker:
   http://llvm.org/bugs/
+
+



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r330889 - Fix a merge conflict that was inadvertently introduced in r330888

2018-04-25 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Wed Apr 25 18:05:05 2018
New Revision: 330889

URL: http://llvm.org/viewvc/llvm-project?rev=330889=rev
Log:
Fix a merge conflict that was inadvertently introduced in r330888 
- during the reversion of r330794

Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=330889=330888=330889=diff
==
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Apr 25 18:05:05 2018
@@ -4021,12 +4021,6 @@ ExprResult Sema::BuildTemplateIdExpr(con
   TemplateKWLoc, TemplateArgs);
   }
 
-  if (R.getAsSingle() && !AnyDependentArguments()) {
-return CheckConceptTemplateId(SS, R.getLookupNameInfo(),
-  R.getAsSingle(),
-  TemplateKWLoc, TemplateArgs);
-  }
-
   // We don't want lookup warnings at this point.
   R.suppressDiagnostics();
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r330888 - Revert rC330794 and some dependent tiny bug fixes

2018-04-25 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Wed Apr 25 17:42:40 2018
New Revision: 330888

URL: http://llvm.org/viewvc/llvm-project?rev=330888=rev
Log:
Revert rC330794 and some dependent tiny bug fixes 

See Richard's humbling feedback here: 
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20180423/226482.html
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20180423/226486.html

Wish I'd had the patience to solicit the feedback prior to committing :)

Sorry for the noise guys.

Thank you Richard for being the steward that clang deserves!




Added:
cfe/trunk/test/Parser/cxx-concept-declaration.cpp
  - copied unchanged from r330793, 
cfe/trunk/test/Parser/cxx-concept-declaration.cpp
Removed:
cfe/trunk/test/Parser/cxx2a-concept-declaration.cpp
Modified:
cfe/trunk/include/clang/AST/DeclTemplate.h
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/include/clang/Basic/DeclNodes.td
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Basic/TemplateKinds.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/include/clang/Serialization/ASTBitCodes.h
cfe/trunk/lib/AST/ASTDumper.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/AST/DeclTemplate.cpp
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/ParseTentative.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Serialization/ASTCommon.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=330888=330887=330888=diff
==
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Wed Apr 25 17:42:40 2018
@@ -3015,46 +3015,6 @@ public:
   static bool classofKind(Kind K) { return K == VarTemplate; }
 };
 
-/// \brief Represents a C++2a ([temp] p1) concept-definition.
-class ConceptDecl : public TemplateDecl {
-protected:
-  Expr *ConstraintExpr;
-
-  ConceptDecl(DeclContext *DC,
-  SourceLocation NameLoc, DeclarationName Name,
-  TemplateParameterList *Params,
-  Expr *ConstraintExpr)
-  : TemplateDecl(nullptr, Concept, DC, NameLoc, Name, Params),
-ConstraintExpr(ConstraintExpr) {};
-public:
-  static ConceptDecl *Create(ASTContext , DeclContext *DC,
- SourceLocation NameLoc, DeclarationName Name,
- TemplateParameterList *Params,
- Expr *ConstraintExpr);
-  static ConceptDecl *CreateDeserialized(ASTContext , unsigned ID);
-
-  Expr *getConstraintExpr() const {
-return ConstraintExpr;
-  }
-
-  void setConstraintExpr(Expr *CE) {
-ConstraintExpr = CE;
-  }
-
-  SourceRange getSourceRange() const override LLVM_READONLY {
-return SourceRange(getTemplateParameters()->getTemplateLoc(),
-   getConstraintExpr()->getLocEnd());
-  }
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
-  static bool classofKind(Kind K) { return K == Concept; }
-
-  friend class ASTReader;
-  friend class ASTDeclReader;
-  friend class ASTDeclWriter;
-};
-
 inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
   if (auto *PD = P.dyn_cast())
 return PD;

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=330888=330887=330888=diff
==
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Apr 25 17:42:40 2018
@@ -1722,13 +1722,6 @@ DEF_TRAVERSE_TMPL_DECL(Class)
 DEF_TRAVERSE_TMPL_DECL(Var)
 DEF_TRAVERSE_TMPL_DECL(Function)
 
-DEF_TRAVERSE_DECL(ConceptDecl, {
-  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-  TRY_TO(TraverseStmt(D->getConstraintExpr()));
-  // FIXME: Traverse all the concept specializations (once we implement forming
-  // template-ids with them).
-})
-
 DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
   // D is the "T" in something like
   //   template  class T> 

Re: r330794 - [c++2a] [concepts] Add rudimentary parsing support for template concept declarations

2018-04-25 Thread Faisal Vali via cfe-commits
On Wed, Apr 25, 2018 at 3:37 PM, Richard Smith <rich...@metafoo.co.uk> wrote:
> On 24 April 2018 at 19:42, Faisal Vali via cfe-commits
> <cfe-commits@lists.llvm.org> wrote:
>>
>> Author: faisalv
>> Date: Tue Apr 24 19:42:26 2018
>> New Revision: 330794
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=330794=rev
>> Log:
>> [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.
>
>
> Is that really worth it? This seems to add complexity to decl-specifier-seq
> / declarator parsing for a construct that has nothing to do with those
> things. I prefer the simpler approach in changyu's patch. I don't think the
> diagnostics you're producing are worthwhile -- the problem is not that
> "concept" can't be combined with other specifiers, it's that it's a
> fundamentally different kind of construct (just like "using X = ...", which
> it's much more like than it is like a declarator declaration).
>

I wouldn't say that I'm certain it's worth it - but then it also
didn't seem to me that the complexity tax being paid was that high
(but probably because my bias leans towards overly-diagnosticating for
users who are still learning the syntax of the language - and i can
imagine folks trying to add types to concept declarations or
attributes - which we may choose to allow in the future..)

Eitherway - I really don't feel strongly about this - just felt it
might be a better service to provide our users - but I do see your
point and the coherence concerns regarding our structure and since you
do feel strongly about it, i'll replace it with changyu's approach.

Sorry about that and thanks for the feedback!


>> 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!
>>
>> Added:
>> cfe/trunk/test/Parser/cxx2a-concept-declaration.cpp
>> Removed:
>> cfe/trunk/test/Parser/cxx-concept-declaration.cpp
>> Modified:
>> cfe/trunk/include/clang/AST/DeclTemplate.h
>> cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>> cfe/trunk/include/clang/Basic/DeclNodes.td
>> cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> cfe/trunk/include/clang/Basic/TemplateKinds.h
>> cfe/trunk/include/clang/Parse/Parser.h
>> cfe/trunk/include/clang/Sema/DeclSpec.h
>> cfe/trunk/include/clang/Sema/Sema.h
>> cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>> cfe/trunk/lib/AST/ASTDumper.cpp
>> cfe/trunk/lib/AST/DeclBase.cpp
>> cfe/trunk/lib/AST/DeclTemplate.cpp
>> cfe/trunk/lib/CodeGen/CGDecl.cpp
>> cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>> cfe/trunk/lib/Parse/ParseDecl.cpp
>> cfe/trunk/lib/Parse/ParseDeclCXX.cpp
>> cfe/trunk/lib/Parse/ParseObjc.cpp
>> cfe/trunk/lib/Parse/ParseTemplate.cpp
>> cfe/trunk/lib/Parse/ParseTentative.cpp
>> cfe/trunk/lib/Parse/Parser.cpp
>> cfe/trunk/lib/Sema/DeclSpec.cpp
>> cfe/trunk/lib/Sema/SemaDecl.cpp
>> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>> cfe/trunk/lib/Sema/SemaTemplate.cpp
>> cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
>> cfe/trunk/lib/Serialization/ASTCommon.cpp
>> cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
>> cfe/trunk/lib/Serialization/ASTWriter.cpp
>> cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
>> cfe/trunk/tools/libclang/CIndex.cpp
>>
>> Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=330794=330793=330794=diff
>>
>> ==
>> --- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
>> +++ cfe/trunk/include/clang/AST/DeclTemplate.h Tue Apr 24 19:42:26 2018
>> @@ -3015,6 +3015,46 @@ public:
>>static bool classofKind(Kind K) { return K == VarTemplate; }
>>  };
>>
>> +/// \brief Represents a C++2a ([temp] p1) concept-definition.
>> +class ConceptDecl : public TemplateDecl {
>> +protected:
>> +  Expr *ConstraintExpr;
>> +
>> +  ConceptDecl(DeclContext *DC,
>> +   

Re: FW: [Diffusion] rC330802: Fix buildbot problems after rC330794

2018-04-25 Thread Faisal Vali via cfe-commits
That should work - although i wonder if we still need makeArrayRef
once we explicitly declare an array - either way thank you for fixing
it Bjorn!!
Faisal Vali



On Wed, Apr 25, 2018 at 4:16 AM, Björn Pettersson A
 wrote:
> Hello Faisal.
>
> Lots of buildbots have failed after your commit "[c++2a] [concepts] Add 
> rudimentary parsing support for template concept declarations" (rC330794)
>
> Here is an example from 
> http://lab.llvm.org:8011/builders/clang-x86_64-linux-abi-test/builds/25483/steps/build-unified-tree/logs/stdio
>

>
> FAILED: tools/clang/lib/Parse/CMakeFiles/clangParse.dir/ParseTemplate.cpp.o
> /usr/bin/c++   -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GNU_SOURCE 
> -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 
> -Itools/clang/lib/Parse 
> -I/home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/lib/Parse
>  
> -I/home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/include
>  -Itools/clang/include -Iinclude 
> -I/home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/include 
> -fPIC -fvisibility-inlines-hidden -std=c++11 -Wall -W -Wno-unused-parameter 
> -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic 
> -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor 
> -Wno-comment -ffunction-sections -fdata-sections -fno-common 
> -Woverloaded-virtual -fno-strict-aliasing -O3-UNDEBUG  -fno-exceptions 
> -fno-rtti -MD -MT 
> tools/clang/lib/Parse/CMakeFiles/clangParse.dir/ParseTemplate.cpp.o -MF 
> tools/clang/lib/Parse/CMakeFiles/clangParse.dir/ParseTemplate.cpp.o.d -o 
> tools/clang/lib/Parse/CMakeFiles/clangParse.dir/ParseTemplate.cpp.o -c 
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/lib/Parse/ParseTemplate.cpp
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/lib/Parse/ParseTemplate.cpp:
>  In member function ‘void 
> clang::Parser::ParseConceptDefinition(clang::SourceLocation, 
> clang::DeclSpec&, const clang::Parser::ParsedTemplateInfo&, 
> clang::AccessSpecifier, clang::Parser::DeclSpecContext)’:
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/lib/Parse/ParseTemplate.cpp:373:62:
>  error: no matching function for call to ‘makeArrayRef( initializer list>)’
>SkipUntil(llvm::makeArrayRef({tok::comma, tok::greater}),
>   ^
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/lib/Parse/ParseTemplate.cpp:373:62:
>  note: candidates are:
> In file included from 
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/include/llvm/ADT/APFloat.h:21:0,
>  from 
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/include/clang/AST/APValue.h:18,
>  from 
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/include/clang/AST/Decl.h:17,
>  from 
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h:20,
>  from 
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/include/clang/AST/ASTContext.h:18,
>  from 
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/lib/Parse/ParseTemplate.cpp:14:
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/include/llvm/ADT/ArrayRef.h:451:15:
>  note: template llvm::ArrayRef llvm::makeArrayRef(const T&)
>ArrayRef makeArrayRef(const T ) {
>^
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/include/llvm/ADT/ArrayRef.h:451:15:
>  note:   template argument deduction/substitution failed:
> /home/buildslave/buildslave1a/clang-x86_64-linux-abi-test/llvm/tools/clang/lib/Parse/ParseTemplate.cpp:373:62:
>  note:   couldn't deduce template parameter ‘T’
>SkipUntil(llvm::makeArrayRef({tok::comma, tok::greater}),
>
> 
>
> I made a quick fix in rC330802, where I use a local array as input to the 
> makeArrayRef.
> With such a fix the code started to compile again for me.
> But I advise you to look at my fix to verify that I did not mess up anything.
>
> Regards,
> Björn
>
> -Original Message-
> From: Bjorn Pettersson via Phabricator [mailto:revi...@reviews.llvm.org]
> Sent: den 25 april 2018 11:08
> To: Björn Pettersson A 
> Subject: [Diffusion] rC330802: Fix buildbot problems after rC330794
>
> bjope committed rC330802: Fix buildbot problems after rC330794.
>
> Fix buildbot problems after https://reviews.llvm.org/rC330794
>
> Avoiding
>
>   error: no matching function for call to 'makeArrayRef'
>
> at
>
>   ../tools/clang/lib/Parse/ParseTemplate.cpp:373:17
>
> By using a local C array as input to makeArrayRef.
>
> Not sure if this is the best solution, but it 

r330798 - [NFC] Make dependent parameter non-deducible, so that we are forced to use the default template parameter.

2018-04-24 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Tue Apr 24 20:54:20 2018
New Revision: 330798

URL: http://llvm.org/viewvc/llvm-project?rev=330798=rev
Log:
[NFC] Make dependent parameter non-deducible, so that we are forced to use the 
default template parameter.

This might provide users with more graceful diagnostics if they should ever try 
and call this function with non-ConceptDecls.

Modified:
cfe/trunk/include/clang/Sema/DeclSpec.h

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=330798=330797=330798=diff
==
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Tue Apr 24 20:54:20 2018
@@ -699,7 +699,8 @@ public:
   // This function can only be instantiated with ConceptDecl.  We made it a
   // template so that ConceptDecl only has to be defined where this is called.
   template 
-  void setConceptRep(ConceptDeclTy *Rep) {
+  void
+  setConceptRep(typename llvm::identity::argument_type *Rep) {
 static_assert(std::is_same::value,
   "Must only be instantiated with ConceptDecl");
 assert(isConceptSpecified() && "DeclSpec does not store a concept");


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r330796 - Fix rC330794 - a parameter that should have been dependent was inadvertently not -

2018-04-24 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Tue Apr 24 20:28:23 2018
New Revision: 330796

URL: http://llvm.org/viewvc/llvm-project?rev=330796=rev
Log:
Fix rC330794 - a parameter that should have been dependent was inadvertently 
not -
 and compiled in MSVC - but not so for the other bots.

The fix was to make it dependent as intended.


Modified:
cfe/trunk/include/clang/Sema/DeclSpec.h

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=330796=330795=330796=diff
==
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Tue Apr 24 20:28:23 2018
@@ -520,6 +520,8 @@ public:
 
 return cast_or_null(DeclRep);
   }
+
+
   Expr *getRepAsExpr() const {
 assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr");
 return ExprRep;
@@ -697,7 +699,7 @@ public:
   // This function can only be instantiated with ConceptDecl.  We made it a
   // template so that ConceptDecl only has to be defined where this is called.
   template 
-  void setConceptRep(ConceptDecl *Rep) {
+  void setConceptRep(ConceptDeclTy *Rep) {
 static_assert(std::is_same::value,
   "Must only be instantiated with ConceptDecl");
 assert(isConceptSpecified() && "DeclSpec does not store a concept");
@@ -706,7 +708,7 @@ public:
"once, and usually right after DeclRep was set to null");
 DeclRep = Rep;
   }
-  
+
   void UpdateTypeRep(ParsedType Rep) {
 assert(isTypeRep((TST) TypeSpecType));
 TypeRep = Rep;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r330794 - [c++2a] [concepts] Add rudimentary parsing support for template concept declarations

2018-04-24 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Tue Apr 24 19:42:26 2018
New Revision: 330794

URL: http://llvm.org/viewvc/llvm-project?rev=330794=rev
Log:
[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!

Added:
cfe/trunk/test/Parser/cxx2a-concept-declaration.cpp
Removed:
cfe/trunk/test/Parser/cxx-concept-declaration.cpp
Modified:
cfe/trunk/include/clang/AST/DeclTemplate.h
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/include/clang/Basic/DeclNodes.td
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Basic/TemplateKinds.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/include/clang/Serialization/ASTBitCodes.h
cfe/trunk/lib/AST/ASTDumper.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/AST/DeclTemplate.cpp
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/ParseTentative.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Serialization/ASTCommon.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=330794=330793=330794=diff
==
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Tue Apr 24 19:42:26 2018
@@ -3015,6 +3015,46 @@ public:
   static bool classofKind(Kind K) { return K == VarTemplate; }
 };
 
+/// \brief Represents a C++2a ([temp] p1) concept-definition.
+class ConceptDecl : public TemplateDecl {
+protected:
+  Expr *ConstraintExpr;
+
+  ConceptDecl(DeclContext *DC,
+  SourceLocation NameLoc, DeclarationName Name,
+  TemplateParameterList *Params,
+  Expr *ConstraintExpr)
+  : TemplateDecl(nullptr, Concept, DC, NameLoc, Name, Params),
+ConstraintExpr(ConstraintExpr) {};
+public:
+  static ConceptDecl *Create(ASTContext , DeclContext *DC,
+ SourceLocation NameLoc, DeclarationName Name,
+ TemplateParameterList *Params,
+ Expr *ConstraintExpr);
+  static ConceptDecl *CreateDeserialized(ASTContext , unsigned ID);
+
+  Expr *getConstraintExpr() const {
+return ConstraintExpr;
+  }
+
+  void setConstraintExpr(Expr *CE) {
+ConstraintExpr = CE;
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+return SourceRange(getTemplateParameters()->getTemplateLoc(),
+   getConstraintExpr()->getLocEnd());
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Concept; }
+
+  friend class ASTReader;
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
 inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
   if (auto *PD = P.dyn_cast())
 return PD;

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=330794=330793=330794=diff
==
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Apr 24 19:42:26 2018
@@ -1722,6 +1722,13 @@ DEF_TRAVERSE_TMPL_DECL(Class)
 DEF_TRAVERSE_TMPL_DECL(Var)
 DEF_TRAVERSE_TMPL_DECL(Function)
 
+DEF_TRAVERSE_DECL(ConceptDecl, {
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+  TRY_TO(TraverseStmt(D->getConstraintExpr()));
+  // FIXME: Traverse all the concept specializations (once we implement forming
+  // template-ids with them).
+})
+
 DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
   // D is the "T" in 

r321628 - Again reverting an attempt to convert the DeclSpec enums into scoped enums.

2018-01-01 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Jan  1 10:23:28 2018
New Revision: 321628

URL: http://llvm.org/viewvc/llvm-project?rev=321628=rev
Log:
Again reverting an attempt to convert the DeclSpec enums into scoped enums.
  - reverts r321622, r321625, and r321626.
  - the use of bit-fields is still resulting in warnings - even though we can 
use static-asserts to harden the code and ensure the bit-fields are wide 
enough.  The bots still complain of warnings being seen.
  - to silence the warnings requires specifying the bit-fields with the 
underlying enum type (as opposed to the enum type itself), which then requires 
lots of unnecessary static casts of each enumerator within DeclSpec to the 
underlying-type, which even though could be seen as implementation details, it 
does hamper readability - and given the additional litterings, makes me 
question the value of the change.

So in short - I give up (for now at least).  

Sorry about the noise.

Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/AST/TypeLoc.h
cfe/trunk/include/clang/Basic/Specifiers.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/AST/TypeLoc.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=321628=321627=321628=diff
==
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Jan  1 10:23:28 2018
@@ -4747,11 +4747,11 @@ public:
   }
 
   /// Converts a type specifier (DeclSpec::TST) into an elaborated type 
keyword.
-  static ElaboratedTypeKeyword getKeywordForTypeSpec(TypeSpecifierType 
TypeSpec);
+  static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
 
   /// Converts a type specifier (DeclSpec::TST) into a tag type kind.
   /// It is an error to provide a type specifier which *isn't* a tag kind here.
-  static TagTypeKind getTagTypeKindForTypeSpec(TypeSpecifierType TypeSpec);
+  static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
 
   /// Converts a TagTypeKind into an elaborated type keyword.
   static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=321628=321627=321628=diff
==
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Jan  1 10:23:28 2018
@@ -598,43 +598,43 @@ public:
 if (needsExtraLocalData())
   return static_cast(getWrittenBuiltinSpecs().Sign);
 else
-  return TypeSpecifierSign::TSS_unspecified;
+  return TSS_unspecified;
   }
 
   bool hasWrittenSignSpec() const {
-return getWrittenSignSpec() != TypeSpecifierSign::TSS_unspecified;
+return getWrittenSignSpec() != TSS_unspecified;
   }
 
   void setWrittenSignSpec(TypeSpecifierSign written) {
 if (needsExtraLocalData())
-  getWrittenBuiltinSpecs().Sign = static_cast(written);
+  getWrittenBuiltinSpecs().Sign = written;
   }
 
   TypeSpecifierWidth getWrittenWidthSpec() const {
 if (needsExtraLocalData())
   return static_cast(getWrittenBuiltinSpecs().Width);
 else
-  return TypeSpecifierWidth::TSW_unspecified;
+  return TSW_unspecified;
   }
 
   bool hasWrittenWidthSpec() const {
-return getWrittenWidthSpec() != TypeSpecifierWidth::TSW_unspecified;
+return getWrittenWidthSpec() != TSW_unspecified;
   }
 
   void setWrittenWidthSpec(TypeSpecifierWidth written) {
 if (needsExtraLocalData())
-  getWrittenBuiltinSpecs().Width = static_cast(written);
+  getWrittenBuiltinSpecs().Width = written;
   }
 
   TypeSpecifierType getWrittenTypeSpec() const;
 
   bool hasWrittenTypeSpec() const {
-return getWrittenTypeSpec() != TypeSpecifierType::TST_unspecified;
+return getWrittenTypeSpec() != TST_unspecified;
   }
 
   void setWrittenTypeSpec(TypeSpecifierType written) {
 if (needsExtraLocalData())
-  getWrittenBuiltinSpecs().Type = static_cast(written);
+  getWrittenBuiltinSpecs().Type = written;
   }
 
   bool hasModeAttr() const {
@@ -653,10 +653,9 @@ public:
 setBuiltinLoc(Loc);
 if 

r321625 - Use 'unsigned int' instead of enum bit-fields to silence some warnings from r321622

2018-01-01 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Jan  1 08:36:47 2018
New Revision: 321625

URL: http://llvm.org/viewvc/llvm-project?rev=321625=rev
Log:
Use 'unsigned int' instead of enum bit-fields to silence some warnings from 
r321622
  - bots were complaining that the bit-field width was less than the width of 
the underlying type (note, underlying types of enums can not be bit-fields)
  - add static_asserts for TSS and TSW to ensure that the bit-fields can hold 
all the enumerators - and add comments next to the last enumerator warning not 
to reorder.

See https://reviews.llvm.org/rC321622 for the patch that introduced the 
warnings.

  

Modified:
cfe/trunk/include/clang/AST/TypeLoc.h
cfe/trunk/include/clang/Basic/Specifiers.h
cfe/trunk/lib/Sema/DeclSpec.cpp

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=321625=321624=321625=diff
==
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Jan  1 08:36:47 2018
@@ -607,7 +607,7 @@ public:
 
   void setWrittenSignSpec(TypeSpecifierSign written) {
 if (needsExtraLocalData())
-  getWrittenBuiltinSpecs().Sign = written;
+  getWrittenBuiltinSpecs().Sign = static_cast(written);
   }
 
   TypeSpecifierWidth getWrittenWidthSpec() const {
@@ -623,7 +623,7 @@ public:
 
   void setWrittenWidthSpec(TypeSpecifierWidth written) {
 if (needsExtraLocalData())
-  getWrittenBuiltinSpecs().Width = written;
+  getWrittenBuiltinSpecs().Width = static_cast(written);
   }
 
   TypeSpecifierType getWrittenTypeSpec() const;
@@ -634,7 +634,7 @@ public:
 
   void setWrittenTypeSpec(TypeSpecifierType written) {
 if (needsExtraLocalData())
-  getWrittenBuiltinSpecs().Type = written;
+  getWrittenBuiltinSpecs().Type = static_cast(written);
   }
 
   bool hasModeAttr() const {
@@ -653,9 +653,10 @@ public:
 setBuiltinLoc(Loc);
 if (needsExtraLocalData()) {
   WrittenBuiltinSpecs  = getWrittenBuiltinSpecs();
-  wbs.Sign = TypeSpecifierSign::TSS_unspecified;
-  wbs.Width = TypeSpecifierWidth::TSW_unspecified;
-  wbs.Type = TypeSpecifierType::TST_unspecified;
+  wbs.Sign = static_cast(TypeSpecifierSign::TSS_unspecified);
+  wbs.Width =
+  static_cast(TypeSpecifierWidth::TSW_unspecified);
+  wbs.Type = static_cast(TypeSpecifierType::TST_unspecified);
   wbs.ModeAttr = false;
 }
   }

Modified: cfe/trunk/include/clang/Basic/Specifiers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Specifiers.h?rev=321625=321624=321625=diff
==
--- cfe/trunk/include/clang/Basic/Specifiers.h (original)
+++ cfe/trunk/include/clang/Basic/Specifiers.h Mon Jan  1 08:36:47 2018
@@ -26,16 +26,18 @@ namespace clang {
 TSW_unspecified,
 TSW_short,
 TSW_long,
-TSW_longlong
+TSW_longlong // This must be the last enumerator (see struct
+ // WrittenBuiltinSpecs below prior to reordering).
   };
   
   /// \brief Specifies the signedness of a type, e.g., signed or unsigned.
   enum class TypeSpecifierSign : unsigned char {
 TSS_unspecified,
 TSS_signed,
-TSS_unsigned
+TSS_unsigned // This must be the last enumerator (see struct
+ // WrittenBuiltinSpecs below prior to reordering).
   };
-  
+
   enum TypeSpecifiersPipe {
 TSP_unspecified,
 TSP_pipe
@@ -46,49 +48,61 @@ namespace clang {
 TST_unspecified,
 TST_void,
 TST_char,
-TST_wchar,// C++ wchar_t
-TST_char16,   // C++11 char16_t
-TST_char32,   // C++11 char32_t
+TST_wchar,  // C++ wchar_t
+TST_char16, // C++11 char16_t
+TST_char32, // C++11 char32_t
 TST_int,
 TST_int128,
-TST_half, // OpenCL half, ARM NEON __fp16
-TST_Float16,  // C11 extension ISO/IEC TS 18661-3
+TST_half,// OpenCL half, ARM NEON __fp16
+TST_Float16, // C11 extension ISO/IEC TS 18661-3
 TST_float,
 TST_double,
 TST_float128,
-TST_bool, // _Bool
-TST_decimal32,// _Decimal32
-TST_decimal64,// _Decimal64
-TST_decimal128,   // _Decimal128
+TST_bool,   // _Bool
+TST_decimal32,  // _Decimal32
+TST_decimal64,  // _Decimal64
+TST_decimal128, // _Decimal128
 TST_enum,
 TST_union,
 TST_struct,
-TST_class,// C++ class type
-TST_interface,// C++ (Microsoft-specific) __interface type
-TST_typename, // Typedef, C++ class-name or enum name, etc.
+TST_class, // C++ class type
+TST_interface, // C++ (Microsoft-specific) __interface type
+TST_typename,  // Typedef, C++ class-name or enum name, etc.
 TST_typeofType,
 TST_typeofExpr,
-TST_decltype, // C++11 decltype
-TST_underlyingType,   // __underlying_type for C++11
-TST_auto,  

r321622 - [NFC] Modernize enums TypeSpecifierWidth, TypeSpecifierSign & TypeSpecifierType into scoped enums with underlying types.

2018-01-01 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Jan  1 07:42:13 2018
New Revision: 321622

URL: http://llvm.org/viewvc/llvm-project?rev=321622=rev
Log:
[NFC] Modernize enums TypeSpecifierWidth, TypeSpecifierSign & TypeSpecifierType 
into scoped enums with underlying types.
  - Since these enums are used as bit-fields - for the bit-fields to be 
interpreted as unsigned, the underlying type must be specified as unsigned.

Previous failed attempt - wherein I did not specify an underlying type - was 
the sum of:
https://reviews.llvm.org/rC321614
https://reviews.llvm.org/rC321615


Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/AST/TypeLoc.h
cfe/trunk/include/clang/Basic/Specifiers.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/AST/TypeLoc.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=321622=321621=321622=diff
==
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Jan  1 07:42:13 2018
@@ -4747,11 +4747,11 @@ public:
   }
 
   /// Converts a type specifier (DeclSpec::TST) into an elaborated type 
keyword.
-  static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
+  static ElaboratedTypeKeyword getKeywordForTypeSpec(TypeSpecifierType 
TypeSpec);
 
   /// Converts a type specifier (DeclSpec::TST) into a tag type kind.
   /// It is an error to provide a type specifier which *isn't* a tag kind here.
-  static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
+  static TagTypeKind getTagTypeKindForTypeSpec(TypeSpecifierType TypeSpec);
 
   /// Converts a TagTypeKind into an elaborated type keyword.
   static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=321622=321621=321622=diff
==
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Jan  1 07:42:13 2018
@@ -598,11 +598,11 @@ public:
 if (needsExtraLocalData())
   return static_cast(getWrittenBuiltinSpecs().Sign);
 else
-  return TSS_unspecified;
+  return TypeSpecifierSign::TSS_unspecified;
   }
 
   bool hasWrittenSignSpec() const {
-return getWrittenSignSpec() != TSS_unspecified;
+return getWrittenSignSpec() != TypeSpecifierSign::TSS_unspecified;
   }
 
   void setWrittenSignSpec(TypeSpecifierSign written) {
@@ -614,11 +614,11 @@ public:
 if (needsExtraLocalData())
   return static_cast(getWrittenBuiltinSpecs().Width);
 else
-  return TSW_unspecified;
+  return TypeSpecifierWidth::TSW_unspecified;
   }
 
   bool hasWrittenWidthSpec() const {
-return getWrittenWidthSpec() != TSW_unspecified;
+return getWrittenWidthSpec() != TypeSpecifierWidth::TSW_unspecified;
   }
 
   void setWrittenWidthSpec(TypeSpecifierWidth written) {
@@ -629,7 +629,7 @@ public:
   TypeSpecifierType getWrittenTypeSpec() const;
 
   bool hasWrittenTypeSpec() const {
-return getWrittenTypeSpec() != TST_unspecified;
+return getWrittenTypeSpec() != TypeSpecifierType::TST_unspecified;
   }
 
   void setWrittenTypeSpec(TypeSpecifierType written) {
@@ -653,9 +653,9 @@ public:
 setBuiltinLoc(Loc);
 if (needsExtraLocalData()) {
   WrittenBuiltinSpecs  = getWrittenBuiltinSpecs();
-  wbs.Sign = TSS_unspecified;
-  wbs.Width = TSW_unspecified;
-  wbs.Type = TST_unspecified;
+  wbs.Sign = TypeSpecifierSign::TSS_unspecified;
+  wbs.Width = TypeSpecifierWidth::TSW_unspecified;
+  wbs.Type = TypeSpecifierType::TST_unspecified;
   wbs.ModeAttr = false;
 }
   }

Modified: cfe/trunk/include/clang/Basic/Specifiers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Specifiers.h?rev=321622=321621=321622=diff
==
--- cfe/trunk/include/clang/Basic/Specifiers.h (original)
+++ cfe/trunk/include/clang/Basic/Specifiers.h Mon Jan  1 07:42:13 2018
@@ -22,7 +22,7 @@
 
 namespace clang {
   /// \brief Specifies the width of a type, e.g., short, 

r321616 - Revert r321614 and r321615

2017-12-31 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Dec 31 18:49:17 2017
New Revision: 321616

URL: http://llvm.org/viewvc/llvm-project?rev=321616=rev
Log:
Revert r321614 and r321615
  - the enum changes to TypeSpecifierType are breaking some tests - and will 
require a more careful integration.

Sorry about rushing these changes - thought I could sneak them in prior to 
heading out for new years ;)

Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/AST/TypeLoc.h
cfe/trunk/include/clang/Basic/Specifiers.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/AST/TypeLoc.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=321616=321615=321616=diff
==
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sun Dec 31 18:49:17 2017
@@ -4747,11 +4747,11 @@ public:
   }
 
   /// Converts a type specifier (DeclSpec::TST) into an elaborated type 
keyword.
-  static ElaboratedTypeKeyword getKeywordForTypeSpec(TypeSpecifierType 
TypeSpec);
+  static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
 
   /// Converts a type specifier (DeclSpec::TST) into a tag type kind.
   /// It is an error to provide a type specifier which *isn't* a tag kind here.
-  static TagTypeKind getTagTypeKindForTypeSpec(TypeSpecifierType TypeSpec);
+  static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
 
   /// Converts a TagTypeKind into an elaborated type keyword.
   static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=321616=321615=321616=diff
==
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Sun Dec 31 18:49:17 2017
@@ -598,11 +598,11 @@ public:
 if (needsExtraLocalData())
   return static_cast(getWrittenBuiltinSpecs().Sign);
 else
-  return TypeSpecifierSign::TSS_unspecified;
+  return TSS_unspecified;
   }
 
   bool hasWrittenSignSpec() const {
-return getWrittenSignSpec() != TypeSpecifierSign::TSS_unspecified;
+return getWrittenSignSpec() != TSS_unspecified;
   }
 
   void setWrittenSignSpec(TypeSpecifierSign written) {
@@ -614,11 +614,11 @@ public:
 if (needsExtraLocalData())
   return static_cast(getWrittenBuiltinSpecs().Width);
 else
-  return TypeSpecifierWidth::TSW_unspecified;
+  return TSW_unspecified;
   }
 
   bool hasWrittenWidthSpec() const {
-return getWrittenWidthSpec() != TypeSpecifierWidth::TSW_unspecified;
+return getWrittenWidthSpec() != TSW_unspecified;
   }
 
   void setWrittenWidthSpec(TypeSpecifierWidth written) {
@@ -629,7 +629,7 @@ public:
   TypeSpecifierType getWrittenTypeSpec() const;
 
   bool hasWrittenTypeSpec() const {
-return getWrittenTypeSpec() != TypeSpecifierType::TST_unspecified;
+return getWrittenTypeSpec() != TST_unspecified;
   }
 
   void setWrittenTypeSpec(TypeSpecifierType written) {
@@ -653,9 +653,9 @@ public:
 setBuiltinLoc(Loc);
 if (needsExtraLocalData()) {
   WrittenBuiltinSpecs  = getWrittenBuiltinSpecs();
-  wbs.Sign = TypeSpecifierSign::TSS_unspecified;
-  wbs.Width = TypeSpecifierWidth::TSW_unspecified;
-  wbs.Type = TypeSpecifierType::TST_unspecified;
+  wbs.Sign = TSS_unspecified;
+  wbs.Width = TSW_unspecified;
+  wbs.Type = TST_unspecified;
   wbs.ModeAttr = false;
 }
   }

Modified: cfe/trunk/include/clang/Basic/Specifiers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Specifiers.h?rev=321616=321615=321616=diff
==
--- cfe/trunk/include/clang/Basic/Specifiers.h (original)
+++ cfe/trunk/include/clang/Basic/Specifiers.h Sun Dec 31 18:49:17 2017
@@ -22,7 +22,7 @@
 
 namespace clang {
   /// \brief Specifies the width of a type, e.g., short, long, or long long.
-  enum class TypeSpecifierWidth {
+  enum TypeSpecifierWidth {
 TSW_unspecified,
 TSW_short,
 TSW_long,
@@ -30,7 +30,7 @@ namespace clang {
   };
   
  

r321615 - Add scope specifiers to updated scoped-enums (that I somehow missed in r321614)

2017-12-31 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Dec 31 18:35:43 2017
New Revision: 321615

URL: http://llvm.org/viewvc/llvm-project?rev=321615=rev
Log:
Add scope specifiers to updated scoped-enums (that I somehow missed in r321614)

Modified:
cfe/trunk/lib/AST/TypeLoc.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/lib/AST/TypeLoc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLoc.cpp?rev=321615=321614=321615=diff
==
--- cfe/trunk/lib/AST/TypeLoc.cpp (original)
+++ cfe/trunk/lib/AST/TypeLoc.cpp Sun Dec 31 18:35:43 2017
@@ -311,19 +311,19 @@ TypeSpecifierType BuiltinTypeLoc::getWri
 return static_cast(getWrittenBuiltinSpecs().Type);
   switch (getTypePtr()->getKind()) {
   case BuiltinType::Void:
-return TST_void;
+return TypeSpecifierType::TST_void;
   case BuiltinType::Bool:
-return TST_bool;
+return TypeSpecifierType::TST_bool;
   case BuiltinType::Char_U:
   case BuiltinType::Char_S:
-return TST_char;
+return TypeSpecifierType::TST_char;
   case BuiltinType::Char16:
-return TST_char16;
+return TypeSpecifierType::TST_char16;
   case BuiltinType::Char32:
-return TST_char32;
+return TypeSpecifierType::TST_char32;
   case BuiltinType::WChar_S:
   case BuiltinType::WChar_U:
-return TST_wchar;
+return TypeSpecifierType::TST_wchar;
   case BuiltinType::UChar:
   case BuiltinType::UShort:
   case BuiltinType::UInt:
@@ -365,7 +365,7 @@ TypeSpecifierType BuiltinTypeLoc::getWri
   case BuiltinType::OCLReserveID:
   case BuiltinType::BuiltinFn:
   case BuiltinType::OMPArraySection:
-return TST_unspecified;
+return TypeSpecifierType::TST_unspecified;
   }
 
   llvm_unreachable("Invalid BuiltinType Kind!");

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=321615=321614=321615=diff
==
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sun Dec 31 18:35:43 2017
@@ -590,9 +590,9 @@ void TypeLocWriter::VisitQualifiedTypeLo
 void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
   Record.AddSourceLocation(TL.getBuiltinLoc());
   if (TL.needsExtraLocalData()) {
-Record.push_back(TL.getWrittenTypeSpec());
-Record.push_back(TL.getWrittenSignSpec());
-Record.push_back(TL.getWrittenWidthSpec());
+Record.push_back(static_cast(TL.getWrittenTypeSpec()));
+Record.push_back(static_cast(TL.getWrittenSignSpec()));
+Record.push_back(static_cast(TL.getWrittenWidthSpec()));
 Record.push_back(TL.hasModeAttr());
   }
 }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r321614 - [NFC] Modernize enums TypeSpecifierWidth, TypeSpecifierSign & TypeSpecifierType into scoped enums.

2017-12-31 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Dec 31 18:19:52 2017
New Revision: 321614

URL: http://llvm.org/viewvc/llvm-project?rev=321614=rev
Log:
[NFC] Modernize enums TypeSpecifierWidth, TypeSpecifierSign & TypeSpecifierType 
into scoped enums.

  

Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/AST/TypeLoc.h
cfe/trunk/include/clang/Basic/Specifiers.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=321614=321613=321614=diff
==
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sun Dec 31 18:19:52 2017
@@ -4747,11 +4747,11 @@ public:
   }
 
   /// Converts a type specifier (DeclSpec::TST) into an elaborated type 
keyword.
-  static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
+  static ElaboratedTypeKeyword getKeywordForTypeSpec(TypeSpecifierType 
TypeSpec);
 
   /// Converts a type specifier (DeclSpec::TST) into a tag type kind.
   /// It is an error to provide a type specifier which *isn't* a tag kind here.
-  static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
+  static TagTypeKind getTagTypeKindForTypeSpec(TypeSpecifierType TypeSpec);
 
   /// Converts a TagTypeKind into an elaborated type keyword.
   static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=321614=321613=321614=diff
==
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Sun Dec 31 18:19:52 2017
@@ -598,11 +598,11 @@ public:
 if (needsExtraLocalData())
   return static_cast(getWrittenBuiltinSpecs().Sign);
 else
-  return TSS_unspecified;
+  return TypeSpecifierSign::TSS_unspecified;
   }
 
   bool hasWrittenSignSpec() const {
-return getWrittenSignSpec() != TSS_unspecified;
+return getWrittenSignSpec() != TypeSpecifierSign::TSS_unspecified;
   }
 
   void setWrittenSignSpec(TypeSpecifierSign written) {
@@ -614,11 +614,11 @@ public:
 if (needsExtraLocalData())
   return static_cast(getWrittenBuiltinSpecs().Width);
 else
-  return TSW_unspecified;
+  return TypeSpecifierWidth::TSW_unspecified;
   }
 
   bool hasWrittenWidthSpec() const {
-return getWrittenWidthSpec() != TSW_unspecified;
+return getWrittenWidthSpec() != TypeSpecifierWidth::TSW_unspecified;
   }
 
   void setWrittenWidthSpec(TypeSpecifierWidth written) {
@@ -629,7 +629,7 @@ public:
   TypeSpecifierType getWrittenTypeSpec() const;
 
   bool hasWrittenTypeSpec() const {
-return getWrittenTypeSpec() != TST_unspecified;
+return getWrittenTypeSpec() != TypeSpecifierType::TST_unspecified;
   }
 
   void setWrittenTypeSpec(TypeSpecifierType written) {
@@ -653,9 +653,9 @@ public:
 setBuiltinLoc(Loc);
 if (needsExtraLocalData()) {
   WrittenBuiltinSpecs  = getWrittenBuiltinSpecs();
-  wbs.Sign = TSS_unspecified;
-  wbs.Width = TSW_unspecified;
-  wbs.Type = TST_unspecified;
+  wbs.Sign = TypeSpecifierSign::TSS_unspecified;
+  wbs.Width = TypeSpecifierWidth::TSW_unspecified;
+  wbs.Type = TypeSpecifierType::TST_unspecified;
   wbs.ModeAttr = false;
 }
   }

Modified: cfe/trunk/include/clang/Basic/Specifiers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Specifiers.h?rev=321614=321613=321614=diff
==
--- cfe/trunk/include/clang/Basic/Specifiers.h (original)
+++ cfe/trunk/include/clang/Basic/Specifiers.h Sun Dec 31 18:19:52 2017
@@ -22,7 +22,7 @@
 
 namespace clang {
   /// \brief Specifies the width of a type, e.g., short, long, or long long.
-  enum TypeSpecifierWidth {
+  enum class TypeSpecifierWidth {
 TSW_unspecified,
 TSW_short,
 TSW_long,
@@ -30,7 +30,7 @@ namespace clang {
   };
   
   /// \brief Specifies the signedness of a type, e.g., signed or unsigned.
-  enum TypeSpecifierSign {
+  enum class TypeSpecifierSign {
 TSS_unspecified,
 TSS_signed,
 TSS_unsigned
@@ -42,7 +42,7 @@ namespace 

r321590 - [NFC] Modernize enum DeclSpecContext into a scoped enum.

2017-12-30 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Dec 30 16:06:40 2017
New Revision: 321590

URL: http://llvm.org/viewvc/llvm-project?rev=321590=rev
Log:
[NFC] Modernize enum DeclSpecContext into a scoped enum.

Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/Parser.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=321590=321589=321590=diff
==
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat Dec 30 16:06:40 2017
@@ -1856,7 +1856,7 @@ private:
   /// A context for parsing declaration specifiers.  TODO: flesh this
   /// out, there are other significant restrictions on specifiers than
   /// would be best implemented in the parser.
-  enum DeclSpecContext {
+  enum class DeclSpecContext {
 DSC_normal, // normal context
 DSC_class,  // class context, enables 'friend'
 DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
@@ -1873,18 +1873,18 @@ private:
   /// trailing-type-specifier)?
   static bool isTypeSpecifier(DeclSpecContext DSC) {
 switch (DSC) {
-case DSC_normal:
-case DSC_template_param:
-case DSC_class:
-case DSC_top_level:
-case DSC_objc_method_result:
-case DSC_condition:
+case DeclSpecContext::DSC_normal:
+case DeclSpecContext::DSC_template_param:
+case DeclSpecContext::DSC_class:
+case DeclSpecContext::DSC_top_level:
+case DeclSpecContext::DSC_objc_method_result:
+case DeclSpecContext::DSC_condition:
   return false;
 
-case DSC_template_type_arg:
-case DSC_type_specifier:
-case DSC_trailing:
-case DSC_alias_declaration:
+case DeclSpecContext::DSC_template_type_arg:
+case DeclSpecContext::DSC_type_specifier:
+case DeclSpecContext::DSC_trailing:
+case DeclSpecContext::DSC_alias_declaration:
   return true;
 }
 llvm_unreachable("Missing DeclSpecContext case");
@@ -1894,18 +1894,18 @@ private:
   /// deduction?
   static bool isClassTemplateDeductionContext(DeclSpecContext DSC) {
 switch (DSC) {
-case DSC_normal:
-case DSC_template_param:
-case DSC_class:
-case DSC_top_level:
-case DSC_condition:
-case DSC_type_specifier:
+case DeclSpecContext::DSC_normal:
+case DeclSpecContext::DSC_template_param:
+case DeclSpecContext::DSC_class:
+case DeclSpecContext::DSC_top_level:
+case DeclSpecContext::DSC_condition:
+case DeclSpecContext::DSC_type_specifier:
   return true;
 
-case DSC_objc_method_result:
-case DSC_template_type_arg:
-case DSC_trailing:
-case DSC_alias_declaration:
+case DeclSpecContext::DSC_objc_method_result:
+case DeclSpecContext::DSC_template_type_arg:
+case DeclSpecContext::DSC_trailing:
+case DeclSpecContext::DSC_alias_declaration:
   return false;
 }
 llvm_unreachable("Missing DeclSpecContext case");
@@ -1954,17 +1954,19 @@ private:
 ParsedAttributesWithRange );
   DeclSpecContext
   getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context);
-  void ParseDeclarationSpecifiers(DeclSpec ,
-const ParsedTemplateInfo  = ParsedTemplateInfo(),
-  AccessSpecifier AS = AS_none,
-  DeclSpecContext DSC = DSC_normal,
-  LateParsedAttrList *LateAttrs = nullptr);
-  bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec , AccessSpecifier AS,
-   DeclSpecContext DSContext,
-   LateParsedAttrList *LateAttrs = 
nullptr);
-
-  void ParseSpecifierQualifierList(DeclSpec , AccessSpecifier AS = AS_none,
-   DeclSpecContext DSC = DSC_normal);
+  void ParseDeclarationSpecifiers(
+  DeclSpec ,
+  const ParsedTemplateInfo  = ParsedTemplateInfo(),
+  AccessSpecifier AS = AS_none,
+  DeclSpecContext DSC = DeclSpecContext::DSC_normal,
+  LateParsedAttrList *LateAttrs = nullptr);
+  bool DiagnoseMissingSemiAfterTagDefinition(
+  DeclSpec , AccessSpecifier AS, DeclSpecContext DSContext,
+  LateParsedAttrList *LateAttrs = nullptr);
+
+  void ParseSpecifierQualifierList(
+  DeclSpec , AccessSpecifier AS = AS_none,
+  DeclSpecContext DSC = DeclSpecContext::DSC_normal);
 
   void ParseObjCTypeQualifierList(ObjCDeclSpec ,
   DeclaratorContext Context);

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=321590=321589=321590=diff

r321574 - [NFC] Modernize enum 'UnqualifiedId::IdKind' into a scoped enum UnqualifiedIdKind.

2017-12-29 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Fri Dec 29 20:15:27 2017
New Revision: 321574

URL: http://llvm.org/viewvc/llvm-project?rev=321574=rev
Log:
[NFC] Modernize enum 'UnqualifiedId::IdKind' into a scoped enum 
UnqualifiedIdKind.


Modified:
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaExprMember.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=321574=321573=321574=diff
==
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Fri Dec 29 20:15:27 2017
@@ -882,6 +882,30 @@ private:
 
 };
 
+/// \brief Describes the kind of unqualified-id parsed.
+enum class UnqualifiedIdKind {
+  /// \brief An identifier.
+  IK_Identifier,
+  /// \brief An overloaded operator name, e.g., operator+.
+  IK_OperatorFunctionId,
+  /// \brief A conversion function name, e.g., operator int.
+  IK_ConversionFunctionId,
+  /// \brief A user-defined literal name, e.g., operator "" _i.
+  IK_LiteralOperatorId,
+  /// \brief A constructor name.
+  IK_ConstructorName,
+  /// \brief A constructor named via a template-id.
+  IK_ConstructorTemplateId,
+  /// \brief A destructor name.
+  IK_DestructorName,
+  /// \brief A template-id, e.g., f.
+  IK_TemplateId,
+  /// \brief An implicit 'self' parameter
+  IK_ImplicitSelfParam,
+  /// \brief A deduction-guide name (a template-name)
+  IK_DeductionGuideName
+};
+
 /// \brief Represents a C++ unqualified-id that has been parsed. 
 class UnqualifiedId {
 private:
@@ -890,28 +914,7 @@ private:
 
 public:
   /// \brief Describes the kind of unqualified-id parsed.
-  enum IdKind {
-/// \brief An identifier.
-IK_Identifier,
-/// \brief An overloaded operator name, e.g., operator+.
-IK_OperatorFunctionId,
-/// \brief A conversion function name, e.g., operator int.
-IK_ConversionFunctionId,
-/// \brief A user-defined literal name, e.g., operator "" _i.
-IK_LiteralOperatorId,
-/// \brief A constructor name.
-IK_ConstructorName,
-/// \brief A constructor named via a template-id.
-IK_ConstructorTemplateId,
-/// \brief A destructor name.
-IK_DestructorName,
-/// \brief A template-id, e.g., f.
-IK_TemplateId,
-/// \brief An implicit 'self' parameter
-IK_ImplicitSelfParam,
-/// \brief A deduction-guide name (a template-name)
-IK_DeductionGuideName
-  } Kind;
+  UnqualifiedIdKind Kind;
 
   struct OFI {
 /// \brief The kind of overloaded operator.
@@ -966,13 +969,14 @@ public:
   
   /// \brief The location of the last token that describes this unqualified-id.
   SourceLocation EndLocation;
-  
-  UnqualifiedId() : Kind(IK_Identifier), Identifier(nullptr) { }
+
+  UnqualifiedId()
+  : Kind(UnqualifiedIdKind::IK_Identifier), Identifier(nullptr) {}
 
   /// \brief Clear out this unqualified-id, setting it to default (invalid) 
   /// state.
   void clear() {
-Kind = IK_Identifier;
+Kind = UnqualifiedIdKind::IK_Identifier;
 Identifier = nullptr;
 StartLocation = SourceLocation();
 EndLocation = SourceLocation();
@@ -985,15 +989,15 @@ public:
   bool isInvalid() const { return !isValid(); }
   
   /// \brief Determine what kind of name we have.
-  IdKind getKind() const { return Kind; }
-  void setKind(IdKind kind) { Kind = kind; } 
+  UnqualifiedIdKind getKind() const { return Kind; }
+  void setKind(UnqualifiedIdKind kind) { Kind = kind; } 
   
   /// \brief Specify that this unqualified-id was parsed as an identifier.
   ///
   /// \param Id the parsed identifier.
   /// \param IdLoc the location of the parsed identifier.
   void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) {
-Kind = IK_Identifier;
+Kind = UnqualifiedIdKind::IK_Identifier;
 Identifier = const_cast(Id);
 StartLocation = EndLocation = IdLoc;
   }
@@ -1022,7 +1026,7 @@ public:
   void setConversionFunctionId(SourceLocation OperatorLoc, 
ParsedType Ty,
SourceLocation EndLoc) {
-Kind = IK_ConversionFunctionId;
+Kind = UnqualifiedIdKind::IK_ConversionFunctionId;
 StartLocation = OperatorLoc;
 EndLocation = EndLoc;
 ConversionFunctionId = Ty;
@@ -1038,7 +1042,7 @@ public:
   /// \param IdLoc the location of the identifier.
   void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc,
   SourceLocation IdLoc) {
-Kind = IK_LiteralOperatorId;
+

r321546 - [NFC] Modernize enum Declarator::TheContext to a type-safe scoped enum.

2017-12-28 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Thu Dec 28 21:41:00 2017
New Revision: 321546

URL: http://llvm.org/viewvc/llvm-project?rev=321546=rev
Log:
[NFC] Modernize enum Declarator::TheContext to a type-safe scoped enum.

Note, we don't do any bitwise manipulations when using them.






Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Parse/RAIIObjectsForParser.h
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/ParseOpenMP.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=321546=321545=321546=diff
==
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Dec 28 21:41:00 2017
@@ -1447,7 +1447,7 @@ private:
 
   bool isTokIdentifier_in() const;
 
-  ParsedType ParseObjCTypeName(ObjCDeclSpec , Declarator::TheContext Ctx,
+  ParsedType ParseObjCTypeName(ObjCDeclSpec , DeclaratorContext Ctx,
ParsedAttributes *ParamAttrs);
   void ParseObjCMethodRequirement();
   Decl *ParseObjCMethodPrototype(
@@ -1920,15 +1920,16 @@ private:
 bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
   };
 
-  DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation ,
+  DeclGroupPtrTy ParseDeclaration(DeclaratorContext Context,
+  SourceLocation ,
   ParsedAttributesWithRange );
-  DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
+  DeclGroupPtrTy ParseSimpleDeclaration(DeclaratorContext Context,
 SourceLocation ,
 ParsedAttributesWithRange ,
 bool RequireSemi,
 ForRangeInit *FRI = nullptr);
-  bool MightBeDeclarator(unsigned Context);
-  DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec , unsigned Context,
+  bool MightBeDeclarator(DeclaratorContext Context);
+  DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec , DeclaratorContext Context,
 SourceLocation *DeclEnd = nullptr,
 ForRangeInit *FRI = nullptr);
   Decl *ParseDeclarationAfterDeclarator(Declarator ,
@@ -1951,7 +1952,8 @@ private:
 const ParsedTemplateInfo ,
 AccessSpecifier AS, DeclSpecContext DSC, 
 ParsedAttributesWithRange );
-  DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context);
+  DeclSpecContext
+  getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context);
   void ParseDeclarationSpecifiers(DeclSpec ,
 const ParsedTemplateInfo  = ParsedTemplateInfo(),
   AccessSpecifier AS = AS_none,
@@ -1965,7 +1967,7 @@ private:
DeclSpecContext DSC = DSC_normal);
 
   void ParseObjCTypeQualifierList(ObjCDeclSpec ,
-  Declarator::TheContext Context);
+  DeclaratorContext Context);
 
   void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec ,
   const ParsedTemplateInfo ,
@@ -2161,8 +2163,8 @@ private:
 
 public:
   TypeResult ParseTypeName(SourceRange *Range = nullptr,
-   Declarator::TheContext Context
- = Declarator::TypeNameContext,
+   DeclaratorContext Context
+ = DeclaratorContext::TypeNameContext,
AccessSpecifier AS = AS_none,
Decl **OwnedType = nullptr,
ParsedAttributes *Attrs = nullptr);
@@ -2512,20 +2514,21 @@ private:
 
   void DiagnoseUnexpectedNamespace(NamedDecl *Context);
 
-  DeclGroupPtrTy ParseNamespace(unsigned Context, SourceLocation ,
+  DeclGroupPtrTy ParseNamespace(DeclaratorContext Context,
+SourceLocation ,
 SourceLocation InlineLoc = SourceLocation());
-  void ParseInnerNamespace(std::vector& IdentLoc,
-   std::vector& Ident,
-   std::vector& NamespaceLoc,
-   unsigned int index, SourceLocation& InlineLoc,
-

r321449 - Add a fixit for attributes incorrectly placed prior to 'struct/class/enum' keyword.

2017-12-25 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Dec 25 14:23:20 2017
New Revision: 321449

URL: http://llvm.org/viewvc/llvm-project?rev=321449=rev
Log:
Add a fixit for attributes incorrectly placed prior to 'struct/class/enum' 
keyword.

Suggest moving the following erroneous attrib list (based on location)
[[]] struct X;  
to 
struct [[]] X;

Additionally, added a fixme for the current implementation that diagnoses 
misplaced attributes to consider using the newly introduced diagnostic (that I 
think is more user-friendly).






Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/test/Parser/c2x-attributes.c
cfe/trunk/test/Parser/cxx-decl.cpp
cfe/trunk/test/Parser/cxx0x-attributes.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=321449=321448=321449=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon Dec 25 14:23:20 
2017
@@ -587,6 +587,7 @@ def ext_using_attribute_ns : ExtWarn<
 def err_using_attribute_ns_conflict : Error<
   "attribute with scope specifier cannot follow default scope specifier">;
 def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
+def err_attributes_misplaced : Error<"misplaced attributes; expected 
attributes here">;
 def err_l_square_l_square_not_attribute : Error<
   "C++11 only allows consecutive left square brackets when "
   "introducing an attribute">;

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=321449=321448=321449=diff
==
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Dec 25 14:23:20 2017
@@ -2200,13 +2200,16 @@ private:
 
   void stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange ,
   DeclSpec , Sema::TagUseKind TUK);
-
-  void ProhibitAttributes(ParsedAttributesWithRange ) {
+  
+  // FixItLoc = possible correct location for the attributes
+  void ProhibitAttributes(ParsedAttributesWithRange ,
+  SourceLocation FixItLoc = SourceLocation()) {
 if (!attrs.Range.isValid()) return;
-DiagnoseProhibitedAttributes(attrs);
+DiagnoseProhibitedAttributes(attrs, FixItLoc);
 attrs.clear();
   }
-  void DiagnoseProhibitedAttributes(ParsedAttributesWithRange );
+  void DiagnoseProhibitedAttributes(ParsedAttributesWithRange , 
+SourceLocation FixItLoc);
 
   // Forbid C++11 and C2x attributes that appear on certain syntactic locations
   // which standard permits but we don't supported yet, for example, attributes

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=321449=321448=321449=diff
==
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Dec 25 14:23:20 2017
@@ -1548,15 +1548,21 @@ void Parser::DiagnoseMisplacedCXX11Attri
   SourceLocation Loc = Tok.getLocation();
   ParseCXX11Attributes(Attrs);
   CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true);
-
+  // FIXME: use err_attributes_misplaced
   Diag(Loc, diag::err_attributes_not_allowed)
 << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)
 << FixItHint::CreateRemoval(AttrRange);
 }
 
-void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange ) {
-  Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
-<< attrs.Range;
+void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange ,
+  const SourceLocation 
CorrectLocation) {
+  if (CorrectLocation.isValid()) {
+CharSourceRange AttrRange(attrs.Range, true);
+Diag(CorrectLocation, diag::err_attributes_misplaced)
+<< FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)
+<< FixItHint::CreateRemoval(AttrRange);
+  } else
+Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) << 
attrs.Range;
 }
 
 void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange ,

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=321449=321448=321449=diff
==
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Dec 25 14:23:20 2017
@@ -930,7 +930,31 @@ Parser::ParseDeclOrFunctionDefInternal(P
   // C99 6.7.2.3p6: Handle "struct-or-union identifier;", 

r321410 - [NFC] Remove a cast rendered unnecessary by r321409

2017-12-23 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Dec 23 11:27:07 2017
New Revision: 321410

URL: http://llvm.org/viewvc/llvm-project?rev=321410=rev
Log:
[NFC] Remove a cast rendered unnecessary by r321409

See https://reviews.llvm.org/rC321409 for additional context.


Modified:
cfe/trunk/lib/Parse/ParseTemplate.cpp

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=321410=321409=321410=diff
==
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Sat Dec 23 11:27:07 2017
@@ -375,7 +375,7 @@ Parser::ParseTemplateParameterList(unsig
 
 if (NamedDecl *TmpParam
   = ParseTemplateParameter(Depth, TemplateParams.size())) {
-  TemplateParams.push_back(dyn_cast(TmpParam));
+  TemplateParams.push_back(TmpParam);
 } else {
   // If we failed to parse a template parameter, skip until we find
   // a comma or closing brace.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r321409 - [NFC] Update the template-parameter parsers and analyzers to return NamedDecl (vs Decl)

2017-12-23 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Dec 23 10:56:34 2017
New Revision: 321409

URL: http://llvm.org/viewvc/llvm-project?rev=321409=rev
Log:
[NFC] Update the template-parameter parsers and analyzers to return NamedDecl 
(vs Decl)

This patch addresses a FIXME and has the template-parameter processing 
functions return a more derived common type NamedDecl (as opposed to a type 
needlessly higher up in the inheritance hierarchy : Decl).  

Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=321409=321408=321409=diff
==
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat Dec 23 10:56:34 2017
@@ -2748,10 +2748,10 @@ private:
   bool ParseTemplateParameterList(unsigned Depth,
   SmallVectorImpl );
   bool isStartOfTemplateTypeParameter();
-  Decl *ParseTemplateParameter(unsigned Depth, unsigned Position);
-  Decl *ParseTypeParameter(unsigned Depth, unsigned Position);
-  Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
-  Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
+  NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position);
+  NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position);
+  NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
+  NamedDecl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
   void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
  SourceLocation CorrectLoc,
  bool AlreadyHasEllipsis,

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=321409=321408=321409=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sat Dec 23 10:56:34 2017
@@ -6064,7 +6064,7 @@ public:
   void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
   TemplateDecl *AdjustDeclIfTemplate(Decl *);
 
-  Decl *ActOnTypeParameter(Scope *S, bool Typename,
+  NamedDecl *ActOnTypeParameter(Scope *S, bool Typename,
SourceLocation EllipsisLoc,
SourceLocation KeyLoc,
IdentifierInfo *ParamName,
@@ -6077,12 +6077,12 @@ public:
  SourceLocation Loc);
   QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
 
-  Decl *ActOnNonTypeTemplateParameter(Scope *S, Declarator ,
+  NamedDecl *ActOnNonTypeTemplateParameter(Scope *S, Declarator ,
   unsigned Depth,
   unsigned Position,
   SourceLocation EqualLoc,
   Expr *DefaultArg);
-  Decl *ActOnTemplateTemplateParameter(Scope *S,
+  NamedDecl *ActOnTemplateTemplateParameter(Scope *S,
SourceLocation TmpLoc,
TemplateParameterList *Params,
SourceLocation EllipsisLoc,

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=321409=321408=321409=diff
==
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Sat Dec 23 10:56:34 2017
@@ -372,8 +372,8 @@ bool
 Parser::ParseTemplateParameterList(unsigned Depth,
  SmallVectorImpl ) {
   while (1) {
-// FIXME: ParseTemplateParameter should probably just return a NamedDecl.
-if (Decl *TmpParam
+
+if (NamedDecl *TmpParam
   = ParseTemplateParameter(Depth, TemplateParams.size())) {
   TemplateParams.push_back(dyn_cast(TmpParam));
 } else {
@@ -480,7 +480,7 @@ bool Parser::isStartOfTemplateTypeParame
 ///   'class' ...[opt] identifier[opt]
 /// 'template' '<' template-parameter-list '>' 'class' identifier[opt]
 ///   = id-expression
-Decl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
+NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
   if (isStartOfTemplateTypeParameter())
 return ParseTypeParameter(Depth, Position);
 
@@ -502,7 +502,7 @@ Decl *Parser::ParseTemplateParameter(uns
 /// 'class' identifier[opt] '=' type-id
 /// 'typename' ...[opt][C++0x] identifier[opt]
 /// 

r321339 - Diagnose the various invalid decl-specifiers on nontype template parameters.

2017-12-21 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Thu Dec 21 19:50:55 2017
New Revision: 321339

URL: http://llvm.org/viewvc/llvm-project?rev=321339=rev
Log:
Diagnose the various invalid decl-specifiers on nontype template parameters.

The standard correctly forbids various decl-specifiers that dont make sense on 
non-type template parameters - such as the extern in:
template struct X;

This patch implements those restrictions (in a fashion similar to the 
corresponding checks on function parameters within ActOnParamDeclarator).

Credit goes to miyuki (Mikhail Maltsev) for drawing attention to this issue,  
authoring the initial versions of this patch, and supporting the effort to 
re-engineer it slightly.  Thank you!

For details of how this patch evolved please see: 
https://reviews.llvm.org/D40705



Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/CXX/temp/temp.param/p2.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=321339=321338=321339=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Dec 21 19:50:55 
2017
@@ -3911,6 +3911,9 @@ def err_template_param_different_kind :
   "%select{|template parameter }0redeclaration">;
 def note_template_param_different_kind : Note<
   "template parameter has a different kind in template argument">;
+
+def err_invalid_decl_specifier_in_nontype_parm : Error<
+  "invalid declaration specifier in template non-type parameter">;
   
 def err_template_nontype_parm_different_type : Error<
   "template non-type parameter has a different type %0 in template "

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=321339=321338=321339=diff
==
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Dec 21 19:50:55 2017
@@ -929,6 +929,60 @@ Decl *Sema::ActOnNonTypeTemplateParamete
   Expr *Default) {
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
 
+  // Check that we have valid decl-specifiers specified.
+  auto CheckValidDeclSpecifiers = [this, ] {
+// C++ [temp.param]
+// p1 
+//   template-parameter:
+// ...
+// parameter-declaration
+// p2 
+//   ... A storage class shall not be specified in a template-parameter
+//   declaration.
+// [dcl.typedef]p1: 
+//   The typedef specifier [...] shall not be used in the 
decl-specifier-seq
+//   of a parameter-declaration
+const DeclSpec  = D.getDeclSpec();
+auto EmitDiag = [this](SourceLocation Loc) {
+  Diag(Loc, diag::err_invalid_decl_specifier_in_nontype_parm)
+  << FixItHint::CreateRemoval(Loc);
+};
+if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified)
+  EmitDiag(DS.getStorageClassSpecLoc());
+
+if (DeclSpec::TSCS TSCS = DS.getThreadStorageClassSpec())
+  EmitDiag(DS.getThreadStorageClassSpecLoc());
+
+// [dcl.inline]p1: 
+//   The inline specifier can be applied only to the declaration or 
+//   definition of a variable or function.
+
+if (DS.isInlineSpecified())
+  EmitDiag(DS.getInlineSpecLoc());
+
+// [dcl.constexpr]p1:
+//   The constexpr specifier shall be applied only to the definition of a 
+//   variable or variable template or the declaration of a function or 
+//   function template.
+
+if (DS.isConstexprSpecified())
+  EmitDiag(DS.getConstexprSpecLoc());
+
+// [dcl.fct.spec]p1:
+//   Function-specifiers can be used only in function declarations.
+
+if (DS.isVirtualSpecified())
+  EmitDiag(DS.getVirtualSpecLoc());
+
+if (DS.isExplicitSpecified())
+  EmitDiag(DS.getExplicitSpecLoc());
+
+if (DS.isNoreturnSpecified())
+  EmitDiag(DS.getNoreturnSpecLoc());
+  };
+
+  CheckValidDeclSpecifiers();
+  
   if (TInfo->getType()->isUndeducedType()) {
 Diag(D.getIdentifierLoc(),
  diag::warn_cxx14_compat_template_nontype_parm_auto_type)

Modified: cfe/trunk/test/CXX/temp/temp.param/p2.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p2.cpp?rev=321339=321338=321339=diff
==
--- cfe/trunk/test/CXX/temp/temp.param/p2.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.param/p2.cpp Thu Dec 21 19:50:55 2017
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -verify %s 
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -DCPP11
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -DCPP17
 
 

r317984 - Adjust r316292 - remove the anonymous union for sharing a bitfield in FunctionDecl.

2017-11-11 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Nov 11 10:02:29 2017
New Revision: 317984

URL: http://llvm.org/viewvc/llvm-project?rev=317984=rev
Log:
Adjust r316292 - remove the anonymous union for sharing a bitfield in 
FunctionDecl.

The anonymous union did NOT save us storage, but instead behaved as if we added 
an additional integer data member to FunctionDecl.  

For additional context, the anonymous union renders the bit fields as 
non-adjacent and prevents them from sharing the same 'memory location' (i.e. 
bit-storage) by requiring the anonymous union object to be appropriately 
aligned.

This was confirmed through discussion with Richard Smith in Albuquerque (ISO 
C++ Meeting)

https://reviews.llvm.org/rL316292

Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=317984=317983=317984=diff
==
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Nov 11 10:02:29 2017
@@ -1678,17 +1678,17 @@ private:
   /// skipped.
   unsigned HasSkippedBody : 1;
 
+  /// Indicates if the function declaration will have a body, once we're done
+  /// parsing it.
+  unsigned WillHaveBody : 1;
+
 protected:
-  // Since a Deduction Guide [C++17] will never have a body, we can share the
-  // storage, and use a different name.
-  union {
-/// Indicates if the function declaration will have a body, once we're done
-/// parsing it.
-unsigned WillHaveBody : 1;
-/// Indicates that the Deduction Guide is the implicitly generated 'copy
-/// deduction candidate' (is used during overload resolution).
-unsigned IsCopyDeductionCandidate : 1;
-  };
+  /// [C++17] Only used by CXXDeductionGuideDecl. Declared here to avoid
+  /// increasing the size of CXXDeductionGuideDecl by the size of an unsigned
+  /// int as opposed to adding a single bit to FunctionDecl.
+  /// Indicates that the Deduction Guide is the implicitly generated 'copy
+  /// deduction candidate' (is used during overload resolution).
+  unsigned IsCopyDeductionCandidate : 1;
 private:
   /// \brief End part of this FunctionDecl's source range.
   ///
@@ -1767,15 +1767,14 @@ protected:
 DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(),
 SClass(S), IsInline(isInlineSpecified),
 IsInlineSpecified(isInlineSpecified), IsExplicitSpecified(false),
-IsVirtualAsWritten(false), IsPure(false),
-HasInheritedPrototype(false), HasWrittenPrototype(true),
-IsDeleted(false), IsTrivial(false), IsDefaulted(false),
-IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
-IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
-InstantiationIsPending(false),
+IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
+HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
+IsDefaulted(false), IsExplicitlyDefaulted(false),
+HasImplicitReturnZero(false), IsLateTemplateParsed(false),
+IsConstexpr(isConstexprSpecified), InstantiationIsPending(false),
 UsesSEHTry(false), HasSkippedBody(false), WillHaveBody(false),
-EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(),
-DNLoc(NameInfo.getInfo()) {}
+IsCopyDeductionCandidate(false), EndRangeLoc(NameInfo.getEndLoc()),
+TemplateOrSpecialization(), DNLoc(NameInfo.getInfo()) {}
 
   typedef Redeclarable redeclarable_base;
   FunctionDecl *getNextRedeclarationImpl() override {

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=317984=317983=317984=diff
==
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Sat Nov 11 10:02:29 2017
@@ -1881,10 +1881,6 @@ private:
 if (EndLocation.isValid())
   setRangeEnd(EndLocation);
 IsExplicitSpecified = IsExplicit;
-
-// IsCopyDeductionCandidate is a union variant member, so ensure it is the
-// active member by storing to it.
-IsCopyDeductionCandidate = false; 
   }
 
 public:

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=317984=317983=317984=diff
==
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sat Nov 11 10:02:29 2017
@@ -1863,8 +1863,7 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CX
 
 void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
   

r316304 - [c++2a] Update cxx_status w __VA_OPT__ marked as completed in SVN.

2017-10-22 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Oct 22 15:29:52 2017
New Revision: 316304

URL: http://llvm.org/viewvc/llvm-project?rev=316304=rev
Log:
[c++2a] Update cxx_status w __VA_OPT__ marked as completed in SVN.

Modified:
cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/www/cxx_status.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=316304=316303=316304=diff
==
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Sun Oct 22 15:29:52 2017
@@ -813,7 +813,7 @@ as the draft C++2a standard evolves.
 
   __VA_OPT__ for preprocessor comma elision
   http://wg21.link/p0306r4;>P0306R4
-  No
+  SVN
 
 
   Designated initializers


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r316292 - [C++17] Fix PR34970 - tweak overload resolution for class template deduction-guides in line with WG21's p0620r0.

2017-10-22 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Oct 22 07:45:08 2017
New Revision: 316292

URL: http://llvm.org/viewvc/llvm-project?rev=316292=rev
Log:
[C++17] Fix PR34970 - tweak overload resolution for class template 
deduction-guides in line with WG21's p0620r0.

In order to identify the copy deduction candidate, I considered two approaches:
  - attempt to determine whether an implicit guide is a copy deduction 
candidate by checking certain properties of its subsituted parameter during 
overload-resolution.
  - using one of the many bits (WillHaveBody) from FunctionDecl (that 
CXXDeductionGuideDecl inherits from) that are otherwise irrelevant for 
deduction guides

After some brittle gymnastics w the first strategy, I settled on the second, 
although to avoid confusion and to give that bit a better name, i turned it 
into a member of an anonymous union.

Given this identification 'bit', the tweak to overload resolution was a simple 
reordering of the deduction guide checks (in 
SemaOverload.cpp::isBetterOverloadCandidate), in-line with Jason Merrill's 
p0620r0 drafting which made it into the working paper.  Concordant with that, I 
made sure the copy deduction candidate is always added.


References:
See https://bugs.llvm.org/show_bug.cgi?id=34970 
See http://wg21.link/p0620r0

Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
cfe/trunk/test/CXX/over/over.match/over.match.best/p1.cpp

cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=316292=316291=316292=diff
==
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sun Oct 22 07:45:08 2017
@@ -1678,10 +1678,18 @@ private:
   /// skipped.
   unsigned HasSkippedBody : 1;
 
-  /// Indicates if the function declaration will have a body, once we're done
-  /// parsing it.
-  unsigned WillHaveBody : 1;
-
+protected:
+  // Since a Deduction Guide [C++17] will never have a body, we can share the
+  // storage, and use a different name.
+  union {
+/// Indicates if the function declaration will have a body, once we're done
+/// parsing it.
+unsigned WillHaveBody : 1;
+/// Indicates that the Deduction Guide is the implicitly generated 'copy
+/// deduction candidate' (is used during overload resolution).
+unsigned IsCopyDeductionCandidate : 1;
+  };
+private:
   /// \brief End part of this FunctionDecl's source range.
   ///
   /// We could compute the full range in getSourceRange(). However, when we're

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=316292=316291=316292=diff
==
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Sun Oct 22 07:45:08 2017
@@ -1881,6 +1881,10 @@ private:
 if (EndLocation.isValid())
   setRangeEnd(EndLocation);
 IsExplicitSpecified = IsExplicit;
+
+// IsCopyDeductionCandidate is a union variant member, so ensure it is the
+// active member by storing to it.
+IsCopyDeductionCandidate = false; 
   }
 
 public:
@@ -1903,6 +1907,12 @@ public:
 return getDeclName().getCXXDeductionGuideTemplate();
   }
 
+  void setIsCopyDeductionCandidate() {
+IsCopyDeductionCandidate = true;
+  }
+
+  bool isCopyDeductionCandidate() const { return IsCopyDeductionCandidate; }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == CXXDeductionGuide; }

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=316292=316291=316292=diff
==
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun Oct 22 07:45:08 2017
@@ -8965,12 +8965,6 @@ bool clang::isBetterOverloadCandidate(
 // C++14 [over.match.best]p1 section 2 bullet 3.
   }
 
-  //-- F1 is generated from a deduction-guide and F2 is not
-  auto *Guide1 = dyn_cast_or_null(Cand1.Function);
-  auto *Guide2 = dyn_cast_or_null(Cand2.Function);
-  if (Guide1 && Guide2 && Guide1->isImplicit() != Guide2->isImplicit())
-return Guide2->isImplicit();
-
   //-- F1 is a non-template function and F2 is a function template
   //   specialization, or, if not that,
   bool Cand1IsSpecialization = Cand1.Function &&
@@ -9015,6 

r315842 - [c++2a] Fix failing regression test related to not adding the extension warning to a diagnostic group (in r315840)

2017-10-14 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Oct 14 19:13:17 2017
New Revision: 315842

URL: http://llvm.org/viewvc/llvm-project?rev=315842=rev
Log:
[c++2a] Fix failing regression test related to not adding the extension warning 
to a diagnostic group (in r315840)

In passing also complete a comment that I left uncompleted.

For ease of reference, here's the parent commit: 
https://reviews.llvm.org/rL315840




Modified:
cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
cfe/trunk/include/clang/Lex/TokenLexer.h

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=315842=315841=315842=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Sat Oct 14 19:13:17 2017
@@ -347,8 +347,11 @@ def ext_pp_comma_expr : Extension<"comma
 def ext_pp_bad_vaargs_use : Extension<
   "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro">;
 
-def ext_pp_bad_vaopt_use : Extension<
-  "__VA_OPT__ can only appear in the expansion of a variadic macro">;
+def ext_pp_bad_vaopt_use
+: ExtWarn<
+  "__VA_OPT__ can only appear in the expansion of a variadic macro">,
+  InGroup;
+
 def err_pp_missing_lparen_in_vaopt_use : Error<
   "missing '(' following __VA_OPT__">;
 def err_pp_vaopt_nested_use : Error<

Modified: cfe/trunk/include/clang/Lex/TokenLexer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/TokenLexer.h?rev=315842=315841=315842=diff
==
--- cfe/trunk/include/clang/Lex/TokenLexer.h (original)
+++ cfe/trunk/include/clang/Lex/TokenLexer.h Sat Oct 14 19:13:17 2017
@@ -201,7 +201,9 @@ private:
   /// the tokens just expanded through __VA_OPT__ processing.  These (sub)
   /// sequence of tokens are folded into one stringified token.
   ///
-  /// \param[in] VCtx - contains information about the  
+  /// \param[in] VCtx - contains relevent contextual information about the
+  /// state of the tokens around and including the __VA_OPT__ token, necessary
+  /// for stringification.
 
   void stringifyVAOPTContents(SmallVectorImpl ,
   const VAOptExpansionContext ,


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r315840 - [c++2a] Implement P0306 __VA_OPT__ (Comma omission and comma deletion)

2017-10-14 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Oct 14 18:26:26 2017
New Revision: 315840

URL: http://llvm.org/viewvc/llvm-project?rev=315840=rev
Log:
[c++2a] Implement P0306 __VA_OPT__ (Comma omission and comma deletion)

This patch implements an extension to the preprocessor:

__VA_OPT__(contents) --> which expands into its contents if variadic arguments 
are supplied to the parent macro, or behaves as an empty token if none.

  - Currently this feature is only enabled for C++2a (this could be enabled, 
with some careful tweaks, for other dialects with the appropriate extension or 
compatibility warnings)

  - The patch was reviewed here: https://reviews.llvm.org/D35782 and asides 
from the above (and moving some of the definition and expansion recognition 
logic into the corresponding state machines), I believe I incorporated all of 
Richard's suggestions.

A few technicalities (most of which were clarified through private 
correspondence between rsmith, hubert and thomas) are worth mentioning.  Given:

#define F(a,...) a #__VA_OPT__(a ## a)  a ## __VA_OPT__(__VA_ARGS__)

- The call F(,) Does not supply any tokens for the variadic arguments and 
hence VA_OPT behaves as a placeholder.
- When expanding VA_OPT (for e.g. F(,1) token pasting occurs eagerly within 
its contents if the contents need to be stringified.
- A hash or a hashhash prior to VA_OPT does not inhibit expansion of 
arguments if they are the first token within VA_OPT.
- When a variadic argument is supplied, argument substitution occurs within 
the contents as does stringification - and these resulting tokens are inserted 
back into the macro expansions token stream just prior to the entire stream 
being rescanned and concatenated.

See wg21.link/P0306 for further details on the feature.


Acknowledgment: This patch would have been poorer if not for Richard Smith's 
usual thoughtful analysis and feedback.

Added:
cfe/trunk/test/Preprocessor/macro_vaopt_check.cpp
cfe/trunk/test/Preprocessor/macro_vaopt_expand.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
cfe/trunk/include/clang/Lex/MacroArgs.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/include/clang/Lex/TokenLexer.h
cfe/trunk/include/clang/Lex/VariadicMacroSupport.h
cfe/trunk/lib/Lex/MacroArgs.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/lib/Lex/Preprocessor.cpp
cfe/trunk/lib/Lex/TokenLexer.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=315840=315839=315840=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Sat Oct 14 18:26:26 2017
@@ -346,6 +346,20 @@ def ext_pp_extra_tokens_at_eol : ExtWarn
 def ext_pp_comma_expr : Extension<"comma operator in operand of #if">;
 def ext_pp_bad_vaargs_use : Extension<
   "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro">;
+
+def ext_pp_bad_vaopt_use : Extension<
+  "__VA_OPT__ can only appear in the expansion of a variadic macro">;
+def err_pp_missing_lparen_in_vaopt_use : Error<
+  "missing '(' following __VA_OPT__">;
+def err_pp_vaopt_nested_use : Error<
+  "__VA_OPT__ cannot be nested within its own replacement tokens">;
+
+def err_vaopt_paste_at_start : Error<
+  "'##' cannot appear at start of __VA_OPT__ argument">;
+
+def err_vaopt_paste_at_end
+: Error<"'##' cannot appear at end of __VA_OPT__ argument">;
+
 def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">, 
InGroup;
 def ext_variadic_macro : Extension<"variadic macros are a C99 feature">,
   InGroup;

Modified: cfe/trunk/include/clang/Lex/MacroArgs.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroArgs.h?rev=315840=315839=315840=diff
==
--- cfe/trunk/include/clang/Lex/MacroArgs.h (original)
+++ cfe/trunk/include/clang/Lex/MacroArgs.h Sat Oct 14 18:26:26 2017
@@ -112,6 +112,20 @@ public:
   /// argument, this returns false.
   bool isVarargsElidedUse() const { return VarargsElided; }
 
+  /// Returns true if the macro was defined with a variadic (ellipsis) 
parameter
+  /// AND was invoked with at least one token supplied as a variadic argument.
+  ///
+  /// \code 
+  ///   #define F(a)  a
+  ///   #define V(a, ...) __VA_OPT__(a)
+  ///   F()<-- returns false on this invocation.
+  ///   V(,a)  <-- returns true on this invocation.
+  ///   V(,)   <-- returns false on this invocation.
+  /// \endcode
+  ///
+ 
+  bool invokedWithVariadicArgument(const MacroInfo *const MI) const;
+
   /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
   /// tokens into the literal string token that should be produced by the C #
   /// preprocessor operator.  If Charify is true, then it should be turned into


r314753 - Add parens around the boolean condition of one of the added asserts in r314747 ...

2017-10-02 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Oct  2 18:33:36 2017
New Revision: 314753

URL: http://llvm.org/viewvc/llvm-project?rev=314753=rev
Log:
Add parens around the boolean condition of one of the added asserts in r314747 
...
  ... in the hopes of teaching the bots the gift of silence ;)

For quick reference: https://reviews.llvm.org/rL314747




  

Modified:
cfe/trunk/lib/Lex/TokenLexer.cpp

Modified: cfe/trunk/lib/Lex/TokenLexer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=314753=314752=314753=diff
==
--- cfe/trunk/lib/Lex/TokenLexer.cpp (original)
+++ cfe/trunk/lib/Lex/TokenLexer.cpp Mon Oct  2 18:33:36 2017
@@ -531,9 +531,9 @@ bool TokenLexer::pasteTokens(Token )
 bool TokenLexer::pasteTokens(Token , ArrayRef TokenStream,
  unsigned int ) {
   assert(CurIdx > 0 && "## can not be the first token within tokens");
-  assert(TokenStream[CurIdx].is(tok::hashhash) ||
+  assert((TokenStream[CurIdx].is(tok::hashhash) ||
  (PP.getLangOpts().MSVCCompat &&
-  isWideStringLiteralFromMacro(LHSTok, TokenStream[CurIdx])) &&
+  isWideStringLiteralFromMacro(LHSTok, TokenStream[CurIdx]))) &&
  "Token at this Index must be ## or part of the MSVC 'L "
  "#macro-arg' pasting pair");
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r314748 - Remove an assertion I added from the refactoring of pasteTokens (https://reviews.llvm.org/rL314747).

2017-10-02 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Oct  2 18:20:40 2017
New Revision: 314748

URL: http://llvm.org/viewvc/llvm-project?rev=314748=rev
Log:
Remove an assertion I added from the refactoring of pasteTokens 
(https://reviews.llvm.org/rL314747).
  - it made the bots v angry!

I'm not exactly sure why the assertion doesn't hold - if anyone has any insight 
- would appreciate it.

Thanks!

Modified:
cfe/trunk/lib/Lex/TokenLexer.cpp

Modified: cfe/trunk/lib/Lex/TokenLexer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=314748=314747=314748=diff
==
--- cfe/trunk/lib/Lex/TokenLexer.cpp (original)
+++ cfe/trunk/lib/Lex/TokenLexer.cpp Mon Oct  2 18:20:40 2017
@@ -537,10 +537,6 @@ bool TokenLexer::pasteTokens(Token 
  "Token at this Index must be ## or part of the MSVC 'L "
  "#macro-arg' pasting pair");
 
-  assert(std::is_trivial::value &&
-  !std::memcmp(, [CurIdx - 1], sizeof(Token)) &&
- "LHSTok must equal the token preceding the hashhash");
-
   // MSVC: If previous token was pasted, this must be a recovery from an 
invalid
   // paste operation. Ignore spaces before this token to mimic MSVC output.
   // Required for generating valid UUID strings in some MS headers.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r314747 - [NFC] Refactor PasteTokens so that it can be passed the Token Stream and Index to start concatenating at.

2017-10-02 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Oct  2 17:52:14 2017
New Revision: 314747

URL: http://llvm.org/viewvc/llvm-project?rev=314747=rev
Log:
[NFC] Refactor PasteTokens so that it can be passed the Token Stream and Index 
to start concatenating at.
  In passing:
- change the name of the function to pasteTokens c/w coding standards
- rename CurToken to CurTokenIdx (since it is not the token, but the index)
- add doxygen comments to document some of pasteTokens' functionality
- use parameter names different from the data member names.

This will be useful for implementing __VA_OPT__ 
(https://reviews.llvm.org/D35782#inline-322587)

Modified:
cfe/trunk/include/clang/Lex/TokenLexer.h
cfe/trunk/lib/Lex/TokenLexer.cpp

Modified: cfe/trunk/include/clang/Lex/TokenLexer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/TokenLexer.h?rev=314747=314746=314747=diff
==
--- cfe/trunk/include/clang/Lex/TokenLexer.h (original)
+++ cfe/trunk/include/clang/Lex/TokenLexer.h Mon Oct  2 17:52:14 2017
@@ -55,9 +55,9 @@ class TokenLexer {
   ///
   unsigned NumTokens;
 
-  /// CurToken - This is the next token that Lex will return.
+  /// This is the index of the next token that Lex will return.
   ///
-  unsigned CurToken;
+  unsigned CurTokenIdx;
 
   /// ExpandLocStart/End - The source location range where this macro was
   /// expanded.
@@ -156,16 +156,39 @@ private:
   /// isAtEnd - Return true if the next lex call will pop this macro off the
   /// include stack.
   bool isAtEnd() const {
-return CurToken == NumTokens;
+return CurTokenIdx == NumTokens;
   }
 
-  /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
-  /// operator.  Read the ## and RHS, and paste the LHS/RHS together.  If there
-  /// are is another ## after it, chomp it iteratively.  Return the result as
-  /// Tok.  If this returns true, the caller should immediately return the
+  /// Concatenates the next (sub-)sequence of \p Tokens separated by '##'
+  /// starting with LHSTok - stopping when we encounter a token that is neither
+  /// '##' nor preceded by '##'.  Places the result back into \p LHSTok and 
sets
+  /// \p CurIdx to point to the token following the last one that was pasted.
+  ///
+  /// Also performs the MSVC extension wide-literal token pasting involved 
with:
+  ///   \code L #macro-arg. \endcode
+  ///
+  /// \param[in,out] LHSTok - Contains the token to the left of '##' in \p
+  /// Tokens upon entry and will contain the resulting concatenated Token upon
+  /// exit.
+  ///
+  /// \param[in] TokenStream - The stream of Tokens we are lexing from.
+  ///
+  /// \param[in,out] CurIdx - Upon entry, \pTokens[\pCurIdx] must equal '##'
+  /// (with the exception of the MSVC extension mentioned above).  Upon exit, 
it
+  /// is set to the index of the token following the last token that was
+  /// concatenated together.
+  ///
+  /// \returns If this returns true, the caller should immediately return the
   /// token.
-  bool PasteTokens(Token );
 
+  bool pasteTokens(Token , ArrayRef TokenStream,
+   unsigned int );
+
+  /// Calls pasteTokens above, passing in the '*this' object's Tokens and
+  /// CurTokenIdx data members.
+  bool pasteTokens(Token );
+
+  
   /// Expand the arguments of a function-like macro so that we can quickly
   /// return preexpanded tokens from Tokens.
   void ExpandFunctionArguments();

Modified: cfe/trunk/lib/Lex/TokenLexer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=314747=314746=314747=diff
==
--- cfe/trunk/lib/Lex/TokenLexer.cpp (original)
+++ cfe/trunk/lib/Lex/TokenLexer.cpp Mon Oct  2 17:52:14 2017
@@ -31,7 +31,7 @@ void TokenLexer::Init(Token , Source
 
   Macro = MI;
   ActualArgs = Actuals;
-  CurToken = 0;
+  CurTokenIdx = 0;
 
   ExpandLocStart = Tok.getLocation();
   ExpandLocEnd = ELEnd;
@@ -90,7 +90,7 @@ void TokenLexer::Init(const Token *TokAr
   OwnsTokens = ownsTokens;
   DisableMacroExpansion = disableMacroExpansion;
   NumTokens = NumToks;
-  CurToken = 0;
+  CurTokenIdx = 0;
   ExpandLocStart = ExpandLocEnd = SourceLocation();
   AtStartOfLine = false;
   HasLeadingSpace = false;
@@ -431,7 +431,7 @@ bool TokenLexer::Lex(Token ) {
 Tok.startToken();
 Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
 Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace || NextTokGetsSpace);
-if (CurToken == 0)
+if (CurTokenIdx == 0)
   Tok.setFlag(Token::LeadingEmptyMacro);
 return PP.HandleEndOfTokenLexer(Tok);
   }
@@ -440,25 +440,25 @@ bool TokenLexer::Lex(Token ) {
 
   // If this is the first token of the expanded result, we inherit spacing
   // properties later.
-  bool isFirstToken = CurToken == 0;
+  bool isFirstToken = CurTokenIdx == 0;
 
   // Get the next token to return.
-  Tok = Tokens[CurToken++];

r314600 - [NFC] Add assertion that we assume a valid macro argument index.

2017-09-30 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Sep 30 12:34:27 2017
New Revision: 314600

URL: http://llvm.org/viewvc/llvm-project?rev=314600=rev
Log:
[NFC] Add assertion that we assume a valid macro argument index.

Modified:
cfe/trunk/lib/Lex/MacroArgs.cpp

Modified: cfe/trunk/lib/Lex/MacroArgs.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroArgs.cpp?rev=314600=314599=314600=diff
==
--- cfe/trunk/lib/Lex/MacroArgs.cpp (original)
+++ cfe/trunk/lib/Lex/MacroArgs.cpp Sat Sep 30 12:34:27 2017
@@ -118,10 +118,13 @@ unsigned MacroArgs::getArgLength(const T
 /// getUnexpArgument - Return the unexpanded tokens for the specified formal.
 ///
 const Token *MacroArgs::getUnexpArgument(unsigned Arg) const {
+
+  assert(Arg < getNumMacroArguments() && "Invalid arg #");
   // The unexpanded argument tokens start immediately after the MacroArgs 
object
   // in memory.
   const Token *Start = getTrailingObjects();
   const Token *Result = Start;
+  
   // Scan to find Arg.
   for (; Arg; ++Result) {
 assert(Result < Start+NumUnexpArgTokens && "Invalid arg #");


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r314595 - [NFC] Sync function call with changes to interface made in r314593.

2017-09-30 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Sep 30 07:36:00 2017
New Revision: 314595

URL: http://llvm.org/viewvc/llvm-project?rev=314595=rev
Log:
[NFC] Sync function call with changes to interface made in r314593.

Modified:
clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp

Modified: clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp?rev=314595=314594=314595=diff
==
--- clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp (original)
+++ clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp Sat Sep 30 
07:36:00 2017
@@ -429,7 +429,7 @@ static std::string getMacroExpandedStrin
 const clang::Token *ArgTok = Args->getUnexpArgument(ArgNo);
 if (Args->ArgNeedsPreexpansion(ArgTok, PP))
   ResultArgToks = &(const_cast(Args))
-  ->getPreExpArgument(ArgNo, MI, PP)[0];
+  ->getPreExpArgument(ArgNo, PP)[0];
 else
   ResultArgToks = ArgTok; // Use non-preexpanded Tokens.
 // If the arg token didn't expand into anything, ignore it.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r314593 - [NFC] Remove superfluous parameter

2017-09-30 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Sep 30 06:58:38 2017
New Revision: 314593

URL: http://llvm.org/viewvc/llvm-project?rev=314593=rev
Log:
[NFC] Remove superfluous parameter 
 - MacroArgs already knows the maximum number of arguments that can be supplied 
to the macro.  No need to pass MacroInfo (information about the macro 
definition) to the call to getPreExpArgument (which by the way might benefit 
from being called getExpandedArgument() ?) for it to compute the number of 
arguments.


Modified:
cfe/trunk/include/clang/Lex/MacroArgs.h
cfe/trunk/lib/Lex/MacroArgs.cpp
cfe/trunk/lib/Lex/TokenLexer.cpp

Modified: cfe/trunk/include/clang/Lex/MacroArgs.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroArgs.h?rev=314593=314592=314593=diff
==
--- cfe/trunk/include/clang/Lex/MacroArgs.h (original)
+++ cfe/trunk/include/clang/Lex/MacroArgs.h Sat Sep 30 06:58:38 2017
@@ -93,7 +93,7 @@ public:
   /// getPreExpArgument - Return the pre-expanded form of the specified
   /// argument.
   const std::vector &
-getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor );
+getPreExpArgument(unsigned Arg, Preprocessor );
 
   /// getStringifiedArgument - Compute, cache, and return the specified 
argument
   /// that has been 'stringified' as required by the # operator.

Modified: cfe/trunk/lib/Lex/MacroArgs.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroArgs.cpp?rev=314593=314592=314593=diff
==
--- cfe/trunk/lib/Lex/MacroArgs.cpp (original)
+++ cfe/trunk/lib/Lex/MacroArgs.cpp Sat Sep 30 06:58:38 2017
@@ -150,14 +150,13 @@ bool MacroArgs::ArgNeedsPreexpansion(con
 
 /// getPreExpArgument - Return the pre-expanded form of the specified
 /// argument.
-const std::vector &
-MacroArgs::getPreExpArgument(unsigned Arg, const MacroInfo *MI, 
- Preprocessor ) {
-  assert(Arg < MI->getNumParams() && "Invalid argument number!");
+const std::vector ::getPreExpArgument(unsigned Arg,
+   Preprocessor ) {
+  assert(Arg < getNumMacroArguments() && "Invalid argument number!");
 
   // If we have already computed this, return it.
-  if (PreExpArgTokens.size() < MI->getNumParams())
-PreExpArgTokens.resize(MI->getNumParams());
+  if (PreExpArgTokens.size() < getNumMacroArguments())
+PreExpArgTokens.resize(getNumMacroArguments());
   
   std::vector  = PreExpArgTokens[Arg];
   if (!Result.empty()) return Result;

Modified: cfe/trunk/lib/Lex/TokenLexer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=314593=314592=314593=diff
==
--- cfe/trunk/lib/Lex/TokenLexer.cpp (original)
+++ cfe/trunk/lib/Lex/TokenLexer.cpp Sat Sep 30 06:58:38 2017
@@ -275,7 +275,7 @@ void TokenLexer::ExpandFunctionArguments
   // avoids some work in common cases.
   const Token *ArgTok = ActualArgs->getUnexpArgument(ArgNo);
   if (ActualArgs->ArgNeedsPreexpansion(ArgTok, PP))
-ResultArgToks = >getPreExpArgument(ArgNo, Macro, PP)[0];
+ResultArgToks = >getPreExpArgument(ArgNo, PP)[0];
   else
 ResultArgToks = ArgTok;  // Use non-preexpanded tokens.
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r314484 - [NFC] Replace 'arguments' with 'parameters' in comments relating to lexing a macro definition.

2017-09-28 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Thu Sep 28 19:43:22 2017
New Revision: 314484

URL: http://llvm.org/viewvc/llvm-project?rev=314484=rev
Log:
[NFC] Replace 'arguments' with 'parameters' in comments relating to lexing a 
macro definition.

Modified:
cfe/trunk/lib/Lex/PPDirectives.cpp

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=314484=314483=314484=diff
==
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Thu Sep 28 19:43:22 2017
@@ -2132,10 +2132,10 @@ void Preprocessor::HandleIncludeMacrosDi
 // Preprocessor Macro Directive Handling.
 
//===--===//
 
-/// ReadMacroParameterList - The ( starting an argument list of a macro
-/// definition has just been read.  Lex the rest of the arguments and the
+/// ReadMacroParameterList - The ( starting a parameter list of a macro
+/// definition has just been read.  Lex the rest of the parameters and the
 /// closing ), updating MI with what we learn.  Return true if an error occurs
-/// parsing the arg list.
+/// parsing the param list.
 bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token ) {
   SmallVector Parameters;
 
@@ -2143,7 +2143,7 @@ bool Preprocessor::ReadMacroParameterLis
 LexUnexpandedToken(Tok);
 switch (Tok.getKind()) {
 case tok::r_paren:
-  // Found the end of the argument list.
+  // Found the end of the parameter list.
   if (Parameters.empty())  // #define FOO()
 return false;
   // Otherwise we have #define FOO(A,)
@@ -2167,7 +2167,7 @@ bool Preprocessor::ReadMacroParameterLis
 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
 return true;
   }
-  // Add the __VA_ARGS__ identifier as an argument.
+  // Add the __VA_ARGS__ identifier as a parameter.
   Parameters.push_back(Ident__VA_ARGS__);
   MI->setIsC99Varargs();
   MI->setParameterList(Parameters, BP);
@@ -2185,7 +2185,7 @@ bool Preprocessor::ReadMacroParameterLis
 return true;
   }
 
-  // If this is already used as an argument, it is used multiple times 
(e.g.
+  // If this is already used as a parameter, it is used multiple times 
(e.g.
   // #define X(A,A.
   if (std::find(Parameters.begin(), Parameters.end(), II) !=
   Parameters.end()) {  // C99 6.10.3p6
@@ -2193,7 +2193,7 @@ bool Preprocessor::ReadMacroParameterLis
 return true;
   }
 
-  // Add the argument to the macro info.
+  // Add the parameter to the macro info.
   Parameters.push_back(II);
 
   // Lex the token after the identifier.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r314483 - [NFC] Rename variable 'Arguments' to 'Parameters' when lexing the Macro Definition.

2017-09-28 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Thu Sep 28 19:17:31 2017
New Revision: 314483

URL: http://llvm.org/viewvc/llvm-project?rev=314483=rev
Log:
[NFC] Rename variable 'Arguments' to 'Parameters' when lexing the Macro 
Definition.

Modified:
cfe/trunk/lib/Lex/PPDirectives.cpp

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=314483=314482=314483=diff
==
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Thu Sep 28 19:17:31 2017
@@ -2137,14 +2137,14 @@ void Preprocessor::HandleIncludeMacrosDi
 /// closing ), updating MI with what we learn.  Return true if an error occurs
 /// parsing the arg list.
 bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token ) {
-  SmallVector Arguments;
+  SmallVector Parameters;
 
   while (true) {
 LexUnexpandedToken(Tok);
 switch (Tok.getKind()) {
 case tok::r_paren:
   // Found the end of the argument list.
-  if (Arguments.empty())  // #define FOO()
+  if (Parameters.empty())  // #define FOO()
 return false;
   // Otherwise we have #define FOO(A,)
   Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
@@ -2168,9 +2168,9 @@ bool Preprocessor::ReadMacroParameterLis
 return true;
   }
   // Add the __VA_ARGS__ identifier as an argument.
-  Arguments.push_back(Ident__VA_ARGS__);
+  Parameters.push_back(Ident__VA_ARGS__);
   MI->setIsC99Varargs();
-  MI->setParameterList(Arguments, BP);
+  MI->setParameterList(Parameters, BP);
   return false;
 case tok::eod:  // #define X(
   Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
@@ -2187,14 +2187,14 @@ bool Preprocessor::ReadMacroParameterLis
 
   // If this is already used as an argument, it is used multiple times 
(e.g.
   // #define X(A,A.
-  if (std::find(Arguments.begin(), Arguments.end(), II) !=
-  Arguments.end()) {  // C99 6.10.3p6
+  if (std::find(Parameters.begin(), Parameters.end(), II) !=
+  Parameters.end()) {  // C99 6.10.3p6
 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
 return true;
   }
 
   // Add the argument to the macro info.
-  Arguments.push_back(II);
+  Parameters.push_back(II);
 
   // Lex the token after the identifier.
   LexUnexpandedToken(Tok);
@@ -2204,7 +2204,7 @@ bool Preprocessor::ReadMacroParameterLis
 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
 return true;
   case tok::r_paren: // #define X(A)
-MI->setParameterList(Arguments, BP);
+MI->setParameterList(Parameters, BP);
 return false;
   case tok::comma:  // #define X(A,
 break;
@@ -2220,7 +2220,7 @@ bool Preprocessor::ReadMacroParameterLis
 }
 
 MI->setIsGNUVarargs();
-MI->setParameterList(Arguments, BP);
+MI->setParameterList(Parameters, BP);
 return false;
   }
 }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r314373 - [NFC] Don't use C++17 standard lib variable template helper traits, instead use ::value.

2017-09-28 Thread Faisal Vali via cfe-commits
Isn't this a C++11 feature though?

I'm not sure what to make of the fact that I haven't gotten any
complaints from the bots in over 12 hrs i think?

Should I just turn it into a comment?

Thanks!

Faisal Vali



On Wed, Sep 27, 2017 at 9:54 PM, James Y Knight <jykni...@google.com> wrote:
> This still doesn't work on some compilers, because
> std::is_trivially_copyable isn't available:
> http://lab.llvm.org:8011/builders/aosp-O3-polly-before-vectorizer-unprofitable/builds/265/steps/build/logs/stdio
>
> On Wed, Sep 27, 2017 at 10:00 PM, Faisal Vali via cfe-commits
> <cfe-commits@lists.llvm.org> wrote:
>>
>> Author: faisalv
>> Date: Wed Sep 27 19:00:40 2017
>> New Revision: 314373
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=314373=rev
>> Log:
>> [NFC] Don't use C++17 standard lib variable template helper traits,
>> instead use ::value.
>>
>> Modified:
>> cfe/trunk/lib/Lex/MacroArgs.cpp
>>
>> Modified: cfe/trunk/lib/Lex/MacroArgs.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroArgs.cpp?rev=314373=314372=314373=diff
>>
>> ==
>> --- cfe/trunk/lib/Lex/MacroArgs.cpp (original)
>> +++ cfe/trunk/lib/Lex/MacroArgs.cpp Wed Sep 27 19:00:40 2017
>> @@ -62,7 +62,7 @@ MacroArgs *MacroArgs::create(const Macro
>>
>>// Copy the actual unexpanded tokens to immediately after the result
>> ptr.
>>if (!UnexpArgTokens.empty()) {
>> -static_assert(std::is_trivially_copyable_v,
>> +static_assert(std::is_trivially_copyable::value,
>>"assume trivial copyability if copying into the "
>>"uninitialized array (as opposed to reusing a cached "
>>"MacroArgs)");
>> @@ -96,7 +96,7 @@ MacroArgs *MacroArgs::deallocate() {
>>// Run the dtor to deallocate the vectors.
>>this->~MacroArgs();
>>// Release the memory for the object.
>> -  static_assert(std::is_trivially_destructible_v,
>> +  static_assert(std::is_trivially_destructible::value,
>>  "assume trivially destructible and forego destructors");
>>free(this);
>>
>>
>>
>> ___
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r314373 - [NFC] Don't use C++17 standard lib variable template helper traits, instead use ::value.

2017-09-27 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Wed Sep 27 19:00:40 2017
New Revision: 314373

URL: http://llvm.org/viewvc/llvm-project?rev=314373=rev
Log:
[NFC] Don't use C++17 standard lib variable template helper traits, instead use 
::value.

Modified:
cfe/trunk/lib/Lex/MacroArgs.cpp

Modified: cfe/trunk/lib/Lex/MacroArgs.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroArgs.cpp?rev=314373=314372=314373=diff
==
--- cfe/trunk/lib/Lex/MacroArgs.cpp (original)
+++ cfe/trunk/lib/Lex/MacroArgs.cpp Wed Sep 27 19:00:40 2017
@@ -62,7 +62,7 @@ MacroArgs *MacroArgs::create(const Macro
 
   // Copy the actual unexpanded tokens to immediately after the result ptr.
   if (!UnexpArgTokens.empty()) {
-static_assert(std::is_trivially_copyable_v,
+static_assert(std::is_trivially_copyable::value,
   "assume trivial copyability if copying into the "
   "uninitialized array (as opposed to reusing a cached "
   "MacroArgs)");
@@ -96,7 +96,7 @@ MacroArgs *MacroArgs::deallocate() {
   // Run the dtor to deallocate the vectors.
   this->~MacroArgs();
   // Release the memory for the object.
-  static_assert(std::is_trivially_destructible_v,
+  static_assert(std::is_trivially_destructible::value,
 "assume trivially destructible and forego destructors");
   free(this);
   


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r314372 - [NFC] Modernize MacroArgs using TrailingObjects

2017-09-27 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Wed Sep 27 18:50:23 2017
New Revision: 314372

URL: http://llvm.org/viewvc/llvm-project?rev=314372=rev
Log:
[NFC] Modernize MacroArgs using TrailingObjects

Refactor MacroArgs to use TrailingObjects when creating a variably sized object 
on the heap to store the unexpanded tokens immediately after the MacroArgs 
object.

Modified:
cfe/trunk/include/clang/Lex/MacroArgs.h
cfe/trunk/lib/Lex/MacroArgs.cpp

Modified: cfe/trunk/include/clang/Lex/MacroArgs.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroArgs.h?rev=314372=314371=314372=diff
==
--- cfe/trunk/include/clang/Lex/MacroArgs.h (original)
+++ cfe/trunk/include/clang/Lex/MacroArgs.h Wed Sep 27 18:50:23 2017
@@ -17,6 +17,7 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Lex/Token.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/TrailingObjects.h"
 #include 
 
 namespace clang {
@@ -26,7 +27,10 @@ namespace clang {
 
 /// MacroArgs - An instance of this class captures information about
 /// the formal arguments specified to a function-like macro invocation.
-class MacroArgs {
+class MacroArgs final 
+: private llvm::TrailingObjects {
+
+  friend TrailingObjects;
   /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
   /// arguments.  All of the actual argument tokens are allocated immediately
   /// after the MacroArgs object in memory.  This is all of the arguments

Modified: cfe/trunk/lib/Lex/MacroArgs.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroArgs.cpp?rev=314372=314371=314372=diff
==
--- cfe/trunk/lib/Lex/MacroArgs.cpp (original)
+++ cfe/trunk/lib/Lex/MacroArgs.cpp Wed Sep 27 18:50:23 2017
@@ -33,7 +33,7 @@ MacroArgs *MacroArgs::create(const Macro
   // See if we have an entry with a big enough argument list to reuse on the
   // free list.  If so, reuse it.
   for (MacroArgs **Entry =  *Entry;
-   Entry = &(*Entry)->ArgCache)
+   Entry = &(*Entry)->ArgCache) {
 if ((*Entry)->NumUnexpArgTokens >= UnexpArgTokens.size() &&
 (*Entry)->NumUnexpArgTokens < ClosestMatch) {
   ResultEnt = Entry;
@@ -44,14 +44,12 @@ MacroArgs *MacroArgs::create(const Macro
   // Otherwise, use the best fit.
   ClosestMatch = (*Entry)->NumUnexpArgTokens;
 }
-
+  }
   MacroArgs *Result;
   if (!ResultEnt) {
-// Allocate memory for a MacroArgs object with the lexer tokens at the end.
-Result = (MacroArgs *)malloc(sizeof(MacroArgs) +
- UnexpArgTokens.size() * sizeof(Token));
-// Construct the MacroArgs object.
-new (Result)
+// Allocate memory for a MacroArgs object with the lexer tokens at the end,
+// and construct the MacroArgs object.
+Result = new (std::malloc(totalSizeToAlloc(UnexpArgTokens.size(
 MacroArgs(UnexpArgTokens.size(), VarargsElided, MI->getNumParams());
   } else {
 Result = *ResultEnt;
@@ -63,9 +61,14 @@ MacroArgs *MacroArgs::create(const Macro
   }
 
   // Copy the actual unexpanded tokens to immediately after the result ptr.
-  if (!UnexpArgTokens.empty())
+  if (!UnexpArgTokens.empty()) {
+static_assert(std::is_trivially_copyable_v,
+  "assume trivial copyability if copying into the "
+  "uninitialized array (as opposed to reusing a cached "
+  "MacroArgs)");
 std::copy(UnexpArgTokens.begin(), UnexpArgTokens.end(), 
-  const_cast(Result->getUnexpArgument(0)));
+  Result->getTrailingObjects());
+  }
 
   return Result;
 }
@@ -93,6 +96,8 @@ MacroArgs *MacroArgs::deallocate() {
   // Run the dtor to deallocate the vectors.
   this->~MacroArgs();
   // Release the memory for the object.
+  static_assert(std::is_trivially_destructible_v,
+"assume trivially destructible and forego destructors");
   free(this);
   
   return Next;
@@ -115,7 +120,7 @@ unsigned MacroArgs::getArgLength(const T
 const Token *MacroArgs::getUnexpArgument(unsigned Arg) const {
   // The unexpanded argument tokens start immediately after the MacroArgs 
object
   // in memory.
-  const Token *Start = (const Token *)(this+1);
+  const Token *Start = getTrailingObjects();
   const Token *Result = Start;
   // Scan to find Arg.
   for (; Arg; ++Result) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r313521 - Another attempt to fix warning discovered by r313487. [-Wunused-lambda-capture]

2017-09-18 Thread Faisal Vali via cfe-commits
thanks!
Faisal Vali



On Mon, Sep 18, 2017 at 4:10 AM, NAKAMURA Takumi  wrote:
> Seems fixed! Thanks!
>
> On Mon, Sep 18, 2017 at 5:27 PM Vitaly Buka via cfe-commits
>  wrote:
>>
>> Author: vitalybuka
>> Date: Mon Sep 18 01:26:01 2017
>> New Revision: 313521
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=313521=rev
>> Log:
>> Another attempt to fix warning discovered by r313487.
>> [-Wunused-lambda-capture]
>>
>> Modified:
>> cfe/trunk/lib/Lex/PPLexerChange.cpp
>>
>> Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=313521=313520=313521=diff
>>
>> ==
>> --- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)
>> +++ cfe/trunk/lib/Lex/PPLexerChange.cpp Mon Sep 18 01:26:01 2017
>> @@ -42,7 +42,7 @@ bool Preprocessor::isInPrimaryFile() con
>>   "Top level include stack isn't our primary lexer?");
>>return std::none_of(
>>IncludeMacroStack.begin() + 1, IncludeMacroStack.end(),
>> -  [this](const IncludeStackInfo ) -> bool { return
>> IsFileLexer(ISI); });
>> +  [&](const IncludeStackInfo ) -> bool { return IsFileLexer(ISI);
>> });
>>  }
>>
>>  /// getCurrentLexer - Return the current file lexer being lexed from.
>> Note
>>
>>
>> ___
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r313487 - Fix the second half of PR34266: Don't implicitly capture '*this' if the members are found in a class unrelated to the enclosing class.

2017-09-17 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Sep 17 08:37:51 2017
New Revision: 313487

URL: http://llvm.org/viewvc/llvm-project?rev=313487=rev
Log:
Fix the second half of PR34266:  Don't implicitly capture '*this' if the 
members are found in a class unrelated to the enclosing class.

https://bugs.llvm.org/show_bug.cgi?id=34266

For e.g.
  struct A {
 void f(int);
 static void f(char);
  };
  struct B {
auto foo() {
  return [&] (auto a) {
 A::f(a); // this should not cause a capture of '*this'
  };
}
  };

The patch does the following:
1) It moves the check to attempt an implicit capture of '*this' by reference 
into the more logical location of when the call is actually built within 
ActOnCallExpr (as opposed to when the unresolved-member-lookup node is created).
  - Reminder: A capture of '*this' by value has to always be an explicit 
capture.

2) It additionally checks whether the naming class of the UnresolvedMemberExpr 
('A' in the example above) is related to the enclosing class ('B' above).

P.S. If you have access to ISO-C++'s CWG reflector, see this thread for some 
potentially related discussion: http://lists.isocpp.org/core/2017/08/2851.php


Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprMember.cpp
cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=313487=313486=313487=diff
==
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Sep 17 08:37:51 2017
@@ -5125,6 +5125,87 @@ static void checkDirectCallValidity(Sema
   }
 }
 
+static bool enclosingClassIsRelatedToClassInWhichMembersWereFound(
+const UnresolvedMemberExpr *const UME, Sema ) {
+
+  const auto GetFunctionLevelDCIfCXXClass =
+  [](Sema ) -> const CXXRecordDecl * {
+const DeclContext *const DC = S.getFunctionLevelDeclContext();
+if (!DC || !DC->getParent())
+  return nullptr;
+
+// If the call to some member function was made from within a member
+// function body 'M' return return 'M's parent.
+if (const auto *MD = dyn_cast(DC))
+  return MD->getParent()->getCanonicalDecl();
+// else the call was made from within a default member initializer of a
+// class, so return the class.
+if (const auto *RD = dyn_cast(DC))
+  return RD->getCanonicalDecl();
+return nullptr;
+  };
+  // If our DeclContext is neither a member function nor a class (in the
+  // case of a lambda in a default member initializer), we can't have an
+  // enclosing 'this'.
+
+  const CXXRecordDecl *const CurParentClass = GetFunctionLevelDCIfCXXClass(S);
+  if (!CurParentClass)
+return false;
+
+  // The naming class for implicit member functions call is the class in which
+  // name lookup starts.
+  const CXXRecordDecl *const NamingClass =
+  UME->getNamingClass()->getCanonicalDecl();
+  assert(NamingClass && "Must have naming class even for implicit access");
+
+  // If the unresolved member functions were found in a 'naming class' that is
+  // related (either the same or derived from) to the class that contains the
+  // member function that itself contained the implicit member access.
+
+  return CurParentClass == NamingClass ||
+ CurParentClass->isDerivedFrom(NamingClass);
+}
+
+static void
+tryImplicitlyCaptureThisIfImplicitMemberFunctionAccessWithDependentArgs(
+Sema , const UnresolvedMemberExpr *const UME, SourceLocation CallLoc) {
+
+  if (!UME)
+return;
+
+  LambdaScopeInfo *const CurLSI = S.getCurLambda();
+  // Only try and implicitly capture 'this' within a C++ Lambda if it hasn't
+  // already been captured, or if this is an implicit member function call (if
+  // it isn't, an attempt to capture 'this' should already have been made).
+  if (!CurLSI || CurLSI->ImpCaptureStyle == CurLSI->ImpCap_None ||
+  !UME->isImplicitAccess() || CurLSI->isCXXThisCaptured())
+return;
+
+  // Check if the naming class in which the unresolved members were found is
+  // related (same as or is a base of) to the enclosing class.
+ 
+  if (!enclosingClassIsRelatedToClassInWhichMembersWereFound(UME, S))
+return;
+  
+
+  DeclContext *EnclosingFunctionCtx = S.CurContext->getParent()->getParent();
+  // If the enclosing function is not dependent, then this lambda is
+  // capture ready, so if we can capture this, do so.
+  if (!EnclosingFunctionCtx->isDependentContext()) {
+// If the current lambda and all enclosing lambdas can capture 'this' -
+// then go ahead and capture 'this' (since our unresolved overload set
+// contains at least one non-static member function).
+if (!S.CheckCXXThisCapture(CallLoc, /*Explcit*/ false, /*Diagnose*/ false))
+  S.CheckCXXThisCapture(CallLoc);
+  } else if (S.CurContext->isDependentContext()) {
+// ... since this is an implicit member 

r311975 - revert r311839 (ongoing cwg discussion)

2017-08-28 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Aug 28 20:04:13 2017
New Revision: 311975

URL: http://llvm.org/viewvc/llvm-project?rev=311975=rev
Log:
revert r311839 (ongoing cwg discussion)

apologies.

Modified:
cfe/trunk/lib/Sema/SemaExprMember.cpp
cfe/trunk/test/SemaCXX/member-expr.cpp

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=311975=311974=311975=diff
==
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Mon Aug 28 20:04:13 2017
@@ -243,6 +243,7 @@ Sema::BuildPossibleImplicitMemberExpr(co
 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true, 
S);
 
   case IMA_Mixed:
+  case IMA_Mixed_Unrelated:
   case IMA_Unresolved:
 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false,
S);
@@ -251,7 +252,6 @@ Sema::BuildPossibleImplicitMemberExpr(co
 Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use)
   << R.getLookupNameInfo().getName();
 // Fall through.
-  case IMA_Mixed_Unrelated:
   case IMA_Static:
   case IMA_Abstract:
   case IMA_Mixed_StaticContext:

Modified: cfe/trunk/test/SemaCXX/member-expr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-expr.cpp?rev=311975=311974=311975=diff
==
--- cfe/trunk/test/SemaCXX/member-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/member-expr.cpp Mon Aug 28 20:04:13 2017
@@ -228,25 +228,3 @@ namespace pr16676 {
 .i;  // expected-error {{member reference type 'pr16676::S *' is a 
pointer; did you mean to use '->'}}
   }
 }
-
-namespace unrelated_class_instance_call_should_be_illformed {
-
-
-struct A {
-  void bar(int) { }
-  static void bar(double) { }
-  
-  void g(int*);
-  static void g(char *);
-};
-
-
-struct B {
-  void f() {
-A::bar(3);  //expected-error{{call to non-static member}}
-A::g((int*)0); //expected-error{{call to non-static member}}
-  }
-};
-
-
-} // ns unrelated_class_mixed_static_nonstatic_call_should_be_illformed


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r311855 - revert changes from r311851.

2017-08-27 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Aug 27 12:00:08 2017
New Revision: 311855

URL: http://llvm.org/viewvc/llvm-project?rev=311855=rev
Log:
revert changes from r311851.

The right answers here (and how clang needs to be tweaked) require further 
analysis (ongoing cwg thread).

sorry.

Modified:
cfe/trunk/lib/Sema/SemaExprMember.cpp
cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=311855=311854=311855=diff
==
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Sun Aug 27 12:00:08 2017
@@ -102,15 +102,15 @@ static IMAKind ClassifyImplicitMemberAcc
   bool hasNonInstance = false;
   bool isField = false;
   BaseSet Classes;
-  for (const NamedDecl *const D : R) {   
+  for (NamedDecl *D : R) {
+// Look through any using decls.
+D = D->getUnderlyingDecl();
+
 if (D->isCXXInstanceMember()) {
-  // Look through any using decls.
-  const NamedDecl *const UnderlyingDecl = D->getUnderlyingDecl();
-  isField |= isa(UnderlyingDecl) ||
- isa(UnderlyingDecl) ||
- isa(UnderlyingDecl);
+  isField |= isa(D) || isa(D) ||
+ isa(D);
 
-  const CXXRecordDecl *R = cast(D->getDeclContext());
+  CXXRecordDecl *R = cast(D->getDeclContext());
   Classes.insert(R->getCanonicalDecl());
 } else
   hasNonInstance = true;

Modified: cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp?rev=311855=311854=311855=diff
==
--- cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp (original)
+++ cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp Sun Aug 27 
12:00:08 2017
@@ -64,26 +64,17 @@ namespace test2 {
 
   template  struct A {
 void foo();
-void foo2();
-static void static_foo();
-static void static_foo2();
-
+
 void test0() {
   Unrelated::foo(); // expected-error {{call to non-static member function 
without an object argument}}
 }
 
 void test1() {
   B::foo();
-  B::foo2(); // expected-error {{call to non-static member function 
without an object argument}}
-  B::static_foo();
-  B::static_foo2();
 }
 
 static void test2() {
   B::foo(); // expected-error {{call to non-static member function 
without an object argument}}
-  B::foo2(); // expected-error {{call to non-static member function 
without an object argument}}
-  B::static_foo();
-  B::static_foo2();
 }
 
 void test3() {
@@ -92,17 +83,15 @@ namespace test2 {
   };
 
   template  struct B : A {
-using A::foo2;
-using A::static_foo2;
   };
-  
+
   template  struct C {
   };
 
   int test() {
 A a;
 a.test0(); // no instantiation note here, decl is ill-formed
-a.test1(); // expected-note {{in instantiation}}
+a.test1();
 a.test2(); // expected-note {{in instantiation}}
 a.test3(); // expected-note {{in instantiation}}
   }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r311851 - Don't see through 'using member-declarations' when determining the relation of any potential implicit object expression to the parent class of the member function containing the function cal

2017-08-27 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Aug 27 09:49:47 2017
New Revision: 311851

URL: http://llvm.org/viewvc/llvm-project?rev=311851=rev
Log:
Don't see through 'using member-declarations' when determining the relation of 
any potential implicit object expression to the parent class of the member 
function containing the function call.

Prior to this patch clang would not error here:

  template  struct B;
  
  template  struct A {
void foo();
void foo2();

void test1() {
  B::foo();  // OK, foo is declared in A - matches type of 'this'.
  B::foo2(); // This should be an error!  
// foo2 is found in B, 'base unrelated' to 'this'.
}
  };

  template  struct B : A {
using A::foo2;
  };


Modified:
cfe/trunk/lib/Sema/SemaExprMember.cpp
cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=311851=311850=311851=diff
==
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Sun Aug 27 09:49:47 2017
@@ -102,15 +102,15 @@ static IMAKind ClassifyImplicitMemberAcc
   bool hasNonInstance = false;
   bool isField = false;
   BaseSet Classes;
-  for (NamedDecl *D : R) {
-// Look through any using decls.
-D = D->getUnderlyingDecl();
-
+  for (const NamedDecl *const D : R) {   
 if (D->isCXXInstanceMember()) {
-  isField |= isa(D) || isa(D) ||
- isa(D);
+  // Look through any using decls.
+  const NamedDecl *const UnderlyingDecl = D->getUnderlyingDecl();
+  isField |= isa(UnderlyingDecl) ||
+ isa(UnderlyingDecl) ||
+ isa(UnderlyingDecl);
 
-  CXXRecordDecl *R = cast(D->getDeclContext());
+  const CXXRecordDecl *R = cast(D->getDeclContext());
   Classes.insert(R->getCanonicalDecl());
 } else
   hasNonInstance = true;

Modified: cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp?rev=311851=311850=311851=diff
==
--- cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp (original)
+++ cfe/trunk/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp Sun Aug 27 
09:49:47 2017
@@ -64,17 +64,26 @@ namespace test2 {
 
   template  struct A {
 void foo();
-
+void foo2();
+static void static_foo();
+static void static_foo2();
+
 void test0() {
   Unrelated::foo(); // expected-error {{call to non-static member function 
without an object argument}}
 }
 
 void test1() {
   B::foo();
+  B::foo2(); // expected-error {{call to non-static member function 
without an object argument}}
+  B::static_foo();
+  B::static_foo2();
 }
 
 static void test2() {
   B::foo(); // expected-error {{call to non-static member function 
without an object argument}}
+  B::foo2(); // expected-error {{call to non-static member function 
without an object argument}}
+  B::static_foo();
+  B::static_foo2();
 }
 
 void test3() {
@@ -83,15 +92,17 @@ namespace test2 {
   };
 
   template  struct B : A {
+using A::foo2;
+using A::static_foo2;
   };
-
+  
   template  struct C {
   };
 
   int test() {
 A a;
 a.test0(); // no instantiation note here, decl is ill-formed
-a.test1();
+a.test1(); // expected-note {{in instantiation}}
 a.test2(); // expected-note {{in instantiation}}
 a.test3(); // expected-note {{in instantiation}}
   }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r311839 - Pass the correct object argument when a member call to an 'unrelated' class is made.

2017-08-26 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Aug 26 19:21:21 2017
New Revision: 311839

URL: http://llvm.org/viewvc/llvm-project?rev=311839=rev
Log:
Pass the correct object argument when a member call to an 'unrelated' class is 
made.

Prior to this patch, clang would do the wrong thing here (see inline comments 
for pre-patch behavior):

  struct A {
void bar(int) { }
static void bar(double) { }

void g(int*);
static void g(char *);
  };


  struct B {
void f() {
  A::bar(3);  // selects (double) ??!!
  A::g((int*)0); // Instead of no object argument, states conversion 
error?!!
}
  };


The fix is as follows:  When we detect that what appears to be an implicit 
member function call (A::bar) is actually a call to a member of a class (A) 
unrelated to the type (B) that contains the member function (B::f) from which 
the call is being made, don't treat it (A::bar) as an Implicit Member Call 
Expression.

P.S. I wonder if there is an existing bug report related to this? 
(Surprisingly, a cursory search did not find one).


Modified:
cfe/trunk/lib/Sema/SemaExprMember.cpp
cfe/trunk/test/SemaCXX/member-expr.cpp

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=311839=311838=311839=diff
==
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Sat Aug 26 19:21:21 2017
@@ -243,7 +243,6 @@ Sema::BuildPossibleImplicitMemberExpr(co
 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true, 
S);
 
   case IMA_Mixed:
-  case IMA_Mixed_Unrelated:
   case IMA_Unresolved:
 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false,
S);
@@ -252,6 +251,7 @@ Sema::BuildPossibleImplicitMemberExpr(co
 Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use)
   << R.getLookupNameInfo().getName();
 // Fall through.
+  case IMA_Mixed_Unrelated:
   case IMA_Static:
   case IMA_Abstract:
   case IMA_Mixed_StaticContext:

Modified: cfe/trunk/test/SemaCXX/member-expr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-expr.cpp?rev=311839=311838=311839=diff
==
--- cfe/trunk/test/SemaCXX/member-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/member-expr.cpp Sat Aug 26 19:21:21 2017
@@ -228,3 +228,25 @@ namespace pr16676 {
 .i;  // expected-error {{member reference type 'pr16676::S *' is a 
pointer; did you mean to use '->'}}
   }
 }
+
+namespace unrelated_class_instance_call_should_be_illformed {
+
+
+struct A {
+  void bar(int) { }
+  static void bar(double) { }
+  
+  void g(int*);
+  static void g(char *);
+};
+
+
+struct B {
+  void f() {
+A::bar(3);  //expected-error{{call to non-static member}}
+A::g((int*)0); //expected-error{{call to non-static member}}
+  }
+};
+
+
+} // ns unrelated_class_mixed_static_nonstatic_call_should_be_illformed


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r311788 - [NFC] Remove a cstyle cast and replace some uses of Decl with NamedDecl during the processing of TemplateParameterLists.

2017-08-25 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Fri Aug 25 11:24:20 2017
New Revision: 311788

URL: http://llvm.org/viewvc/llvm-project?rev=311788=rev
Log:
[NFC] Remove a cstyle cast and replace some uses of Decl with NamedDecl during 
the processing of TemplateParameterLists.

Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=311788=311787=311788=diff
==
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Aug 25 11:24:20 2017
@@ -2724,11 +2724,11 @@ private:
AccessSpecifier AS=AS_none,
AttributeList *AccessAttrs = nullptr);
   bool ParseTemplateParameters(unsigned Depth,
-   SmallVectorImpl ,
+   SmallVectorImpl ,
SourceLocation ,
SourceLocation );
   bool ParseTemplateParameterList(unsigned Depth,
-  SmallVectorImpl );
+  SmallVectorImpl );
   bool isStartOfTemplateTypeParameter();
   Decl *ParseTemplateParameter(unsigned Depth, unsigned Position);
   Decl *ParseTypeParameter(unsigned Depth, unsigned Position);

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=311788=311787=311788=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Aug 25 11:24:20 2017
@@ -6052,7 +6052,7 @@ public:
  SourceLocation ExportLoc,
  SourceLocation TemplateLoc,
  SourceLocation LAngleLoc,
- ArrayRef Params,
+ ArrayRef Params,
  SourceLocation RAngleLoc,
  Expr *RequiresClause);
 

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=311788=311787=311788=diff
==
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Fri Aug 25 11:24:20 2017
@@ -112,7 +112,7 @@ Parser::ParseTemplateDeclarationOrSpecia
 
 // Parse the '<' template-parameter-list '>'
 SourceLocation LAngleLoc, RAngleLoc;
-SmallVector TemplateParams;
+SmallVector TemplateParams;
 if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(),
 TemplateParams, LAngleLoc, RAngleLoc)) {
   // Skip until the semi-colon or a '}'.
@@ -329,10 +329,9 @@ Parser::ParseSingleDeclarationAfterTempl
 /// that enclose this template parameter list.
 ///
 /// \returns true if an error occurred, false otherwise.
-bool Parser::ParseTemplateParameters(unsigned Depth,
-   SmallVectorImpl ,
- SourceLocation ,
- SourceLocation ) {
+bool Parser::ParseTemplateParameters(
+unsigned Depth, SmallVectorImpl ,
+SourceLocation , SourceLocation ) {
   // Get the template parameter list.
   if (!TryConsumeToken(tok::less, LAngleLoc)) {
 Diag(Tok.getLocation(), diag::err_expected_less_after) << "template";
@@ -370,11 +369,12 @@ bool Parser::ParseTemplateParameters(uns
 /// template-parameter-list ',' template-parameter
 bool
 Parser::ParseTemplateParameterList(unsigned Depth,
- SmallVectorImpl ) {
+ SmallVectorImpl ) {
   while (1) {
+// FIXME: ParseTemplateParameter should probably just return a NamedDecl.
 if (Decl *TmpParam
   = ParseTemplateParameter(Depth, TemplateParams.size())) {
-  TemplateParams.push_back(TmpParam);
+  TemplateParams.push_back(dyn_cast(TmpParam));
 } else {
   // If we failed to parse a template parameter, skip until we find
   // a comma or closing brace.
@@ -569,7 +569,7 @@ Parser::ParseTemplateTemplateParameter(u
 
   // Handle the template <...> part.
   SourceLocation TemplateLoc = ConsumeToken();
-  SmallVector TemplateParams;
+  SmallVector TemplateParams;
   SourceLocation LAngleLoc, RAngleLoc;
   {
 ParseScope TemplateParmScope(this, Scope::TemplateParamScope);

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: 

r308948 - [NFC] Use RAII to un-poison and then re-poison __VA_ARGS__

2017-07-24 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Jul 24 20:15:36 2017
New Revision: 308948

URL: http://llvm.org/viewvc/llvm-project?rev=308948=rev
Log:
[NFC] Use RAII to un-poison and then re-poison __VA_ARGS__
  - This will also be used for the forthcoming __VA_OPT__ feature approved for 
C++2a.
  - recommended by rsmith during his review of the __VA_OPT__ patch 
(https://reviews.llvm.org/D35782)

Added:
cfe/trunk/include/clang/Lex/VariadicMacroSupport.h
Modified:
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Lex/PPDirectives.cpp

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=308948=308947=308948=diff
==
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Mon Jul 24 20:15:36 2017
@@ -96,6 +96,7 @@ enum MacroUse {
 /// know anything about preprocessor-level issues like the \#include stack,
 /// token expansion, etc.
 class Preprocessor {
+  friend class VariadicMacroScopeGuard;
   std::shared_ptr PPOpts;
   DiagnosticsEngine*Diags;
   LangOptions   

Added: cfe/trunk/include/clang/Lex/VariadicMacroSupport.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/VariadicMacroSupport.h?rev=308948=auto
==
--- cfe/trunk/include/clang/Lex/VariadicMacroSupport.h (added)
+++ cfe/trunk/include/clang/Lex/VariadicMacroSupport.h Mon Jul 24 20:15:36 2017
@@ -0,0 +1,56 @@
+//===- VariadicMacroSupport.h - scope-guards etc. -*- C++ 
-*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This file defines support types to help with preprocessing variadic macro 
+// (i.e. macros that use: ellipses __VA_ARGS__ ) definitions and 
+// expansions.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LEX_VARIADICMACROSUPPORT_H
+#define LLVM_CLANG_LEX_VARIADICMACROSUPPORT_H
+
+#include "clang/Lex/Preprocessor.h"
+
+namespace clang {
+
+/// An RAII class that tracks when the Preprocessor starts and stops lexing the
+/// definition of a (ISO C/C++) variadic macro.  As an example, this is useful
+/// for unpoisoning and repoisoning certain identifiers (such as __VA_ARGS__)
+/// that are only allowed in this context.  Also, being a friend of the
+/// Preprocessor class allows it to access PP's cached identifiers directly (as
+/// opposed to performing a lookup each time).
+class VariadicMacroScopeGuard {
+  const Preprocessor 
+  IdentifierInfo __VA_ARGS__;
+
+public:
+  VariadicMacroScopeGuard(const Preprocessor )
+  : PP(P), Ident__VA_ARGS__(*PP.Ident__VA_ARGS__) {
+assert(Ident__VA_ARGS__.isPoisoned() && "__VA_ARGS__ should be poisoned "
+"outside an ISO C/C++ variadic "
+"macro definition!");
+  }
+
+  /// Client code should call this function just before the Preprocessor is
+  /// about to Lex tokens from the definition of a variadic (ISO C/C++) macro.
+  void enterScope() { Ident__VA_ARGS__.setIsPoisoned(false); }
+
+  /// Client code should call this function as soon as the Preprocessor has
+  /// either completed lexing the macro's definition tokens, or an error 
occured
+  /// and the context is being exited.  This function is idempotent (might be
+  /// explicitly called, and then reinvoked via the destructor).
+  void exitScope() { Ident__VA_ARGS__.setIsPoisoned(true); }
+  
+  ~VariadicMacroScopeGuard() { exitScope(); }
+};
+
+}  // end namespace clang
+
+#endif

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=308948=308947=308948=diff
==
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Mon Jul 24 20:15:36 2017
@@ -33,6 +33,7 @@
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Lex/PTHLexer.h"
 #include "clang/Lex/Token.h"
+#include "clang/Lex/VariadicMacroSupport.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
@@ -2290,6 +2291,10 @@ MacroInfo *Preprocessor::ReadOptionalMac
   Token Tok;
   LexUnexpandedToken(Tok);
 
+  // Used to un-poison and then re-poison identifiers of the __VA_ARGS__ ilk
+  // within their appropriate context.
+  VariadicMacroScopeGuard VariadicMacroScopeGuard(*this);
+
   // If this is a function-like macro definition, parse the argument list,
   // marking each of the identifiers as being used as macro arguments.  Also,
   // 

r308823 - [NFC, documentation] Prefer the term expansion instead of macro instantiation

2017-07-22 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Jul 22 05:04:37 2017
New Revision: 308823

URL: http://llvm.org/viewvc/llvm-project?rev=308823=rev
Log:
[NFC, documentation] Prefer the term expansion instead of macro instantiation 

... in the few remaining places where this was not corrected.


  

Modified:
cfe/trunk/docs/InternalsManual.rst

Modified: cfe/trunk/docs/InternalsManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/InternalsManual.rst?rev=308823=308822=308823=diff
==
--- cfe/trunk/docs/InternalsManual.rst (original)
+++ cfe/trunk/docs/InternalsManual.rst Sat Jul 22 05:04:37 2017
@@ -493,11 +493,11 @@ source code of the program.  Important d
 
 In practice, the ``SourceLocation`` works together with the ``SourceManager``
 class to encode two pieces of information about a location: its spelling
-location and its instantiation location.  For most tokens, these will be the
+location and its expansion location.  For most tokens, these will be the
 same.  However, for a macro expansion (or tokens that came from a ``_Pragma``
 directive) these will describe the location of the characters corresponding to
 the token and the location where the token was used (i.e., the macro
-instantiation point or the location of the ``_Pragma`` itself).
+expansion point or the location of the ``_Pragma`` itself).
 
 The Clang front-end inherently depends on the location of a token being tracked
 correctly.  If it is ever incorrect, the front-end may get confused and die.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r308574 - [NFC] Update local variable names to upper-case as per LLVM Coding Standards.

2017-07-19 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Wed Jul 19 18:10:56 2017
New Revision: 308574

URL: http://llvm.org/viewvc/llvm-project?rev=308574=rev
Log:
[NFC] Update local variable names to upper-case as per LLVM Coding Standards.

Modified:
cfe/trunk/lib/Lex/TokenLexer.cpp

Modified: cfe/trunk/lib/Lex/TokenLexer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=308574=308573=308574=diff
==
--- cfe/trunk/lib/Lex/TokenLexer.cpp (original)
+++ cfe/trunk/lib/Lex/TokenLexer.cpp Wed Jul 19 18:10:56 2017
@@ -178,28 +178,28 @@ void TokenLexer::ExpandFunctionArguments
   // we install the newly expanded sequence as the new 'Tokens' list.
   bool MadeChange = false;
 
-  for (unsigned i = 0, e = NumTokens; i != e; ++i) {
+  for (unsigned I = 0, E = NumTokens; I != E; ++I) {
 // If we found the stringify operator, get the argument stringified.  The
 // preprocessor already verified that the following token is a macro name
 // when the #define was parsed.
-const Token  = Tokens[i];
+const Token  = Tokens[I];
 // We don't want a space for the next token after a paste
 // operator.  In valid code, the token will get smooshed onto the
 // preceding one anyway. In assembler-with-cpp mode, invalid
 // pastes are allowed through: in this case, we do not want the
 // extra whitespace to be added.  For example, we want ". ## foo"
 // -> ".foo" not ". foo".
-if (i != 0 && !Tokens[i-1].is(tok::hashhash) && CurTok.hasLeadingSpace())
+if (I != 0 && !Tokens[I-1].is(tok::hashhash) && CurTok.hasLeadingSpace())
   NextTokGetsSpace = true;
 
 if (CurTok.isOneOf(tok::hash, tok::hashat)) {
-  int ArgNo = Macro->getParameterNum(Tokens[i+1].getIdentifierInfo());
+  int ArgNo = Macro->getParameterNum(Tokens[I+1].getIdentifierInfo());
   assert(ArgNo != -1 && "Token following # is not an argument?");
 
   SourceLocation ExpansionLocStart =
   getExpansionLocForMacroDefLoc(CurTok.getLocation());
   SourceLocation ExpansionLocEnd =
-  getExpansionLocForMacroDefLoc(Tokens[i+1].getLocation());
+  getExpansionLocForMacroDefLoc(Tokens[I+1].getLocation());
 
   Token Res;
   if (CurTok.is(tok::hash))  // Stringify
@@ -222,7 +222,7 @@ void TokenLexer::ExpandFunctionArguments
 
   ResultToks.push_back(Res);
   MadeChange = true;
-  ++i;  // Skip arg name.
+  ++I;  // Skip arg name.
   NextTokGetsSpace = false;
   continue;
 }
@@ -230,8 +230,8 @@ void TokenLexer::ExpandFunctionArguments
 // Find out if there is a paste (##) operator before or after the token.
 bool NonEmptyPasteBefore =
   !ResultToks.empty() && ResultToks.back().is(tok::hashhash);
-bool PasteBefore = i != 0 && Tokens[i-1].is(tok::hashhash);
-bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash);
+bool PasteBefore = I != 0 && Tokens[I-1].is(tok::hashhash);
+bool PasteAfter = I+1 != E && Tokens[I+1].is(tok::hashhash);
 assert(!NonEmptyPasteBefore || PasteBefore);
 
 // Otherwise, if this is not an argument token, just add the token to the
@@ -374,7 +374,7 @@ void TokenLexer::ExpandFunctionArguments
 if (PasteAfter) {
   // Discard the argument token and skip (don't copy to the expansion
   // buffer) the paste operator after it.
-  ++i;
+  ++I;
   continue;
 }
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r308191 - [NFC] Update function call names as changed in MacroInfo that should refer to Parameters (as opposed to Arguments).

2017-07-17 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Jul 17 10:20:57 2017
New Revision: 308191

URL: http://llvm.org/viewvc/llvm-project?rev=308191=rev
Log:
[NFC] Update function call names as changed in MacroInfo that should refer to 
Parameters (as opposed to Arguments).

This syncs them up with clang commit r308190

Thanks!

Modified:
clang-tools-extra/trunk/clang-tidy/misc/MacroParenthesesCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/MacroParenthesesCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MacroParenthesesCheck.cpp?rev=308191=308190=308191=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/MacroParenthesesCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MacroParenthesesCheck.cpp Mon Jul 
17 10:20:57 2017
@@ -185,7 +185,7 @@ void MacroParenthesesPPCallbacks::argume
   continue;
 
 // Only interested in macro arguments.
-if (MI->getArgumentNum(Tok.getIdentifierInfo()) < 0)
+if (MI->getParameterNum(Tok.getIdentifierInfo()) < 0)
   continue;
 
 // Argument is surrounded with parentheses/squares/braces/commas.

Modified: 
clang-tools-extra/trunk/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp?rev=308191=308190=308191=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MacroRepeatedSideEffectsCheck.cpp 
Mon Jul 17 10:20:57 2017
@@ -58,8 +58,8 @@ void MacroRepeatedPPCallbacks::MacroExpa
   }) != MI->tokens().end())
 return;
 
-  for (unsigned ArgNo = 0U; ArgNo < MI->getNumArgs(); ++ArgNo) {
-const IdentifierInfo *Arg = *(MI->arg_begin() + ArgNo);
+  for (unsigned ArgNo = 0U; ArgNo < MI->getNumParams(); ++ArgNo) {
+const IdentifierInfo *Arg = *(MI->param_begin() + ArgNo);
 const Token *ResultArgToks = Args->getUnexpArgument(ArgNo);
 
 if (hasSideEffects(ResultArgToks) &&

Modified: clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp?rev=308191=308190=308191=diff
==
--- clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp (original)
+++ clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp Mon Jul 17 
10:20:57 2017
@@ -407,7 +407,7 @@ static std::string getMacroExpandedStrin
   // Walk over the macro Tokens.
   for (const auto  : MI->tokens()) {
 clang::IdentifierInfo *II = T.getIdentifierInfo();
-int ArgNo = (II && Args ? MI->getArgumentNum(II) : -1);
+int ArgNo = (II && Args ? MI->getParameterNum(II) : -1);
 if (ArgNo == -1) {
   // This isn't an argument, just add it.
   if (II == nullptr)


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r308190 - [NFC] Refactor the Preprocessor function that handles Macro definitions and rename Arguments to Parameters in Macro Definitions.

2017-07-17 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Jul 17 10:18:43 2017
New Revision: 308190

URL: http://llvm.org/viewvc/llvm-project?rev=308190=rev
Log:
[NFC] Refactor the Preprocessor function that handles Macro definitions and 
rename Arguments to Parameters in Macro Definitions. 
  - Extracted the reading of the tokens out into a separate function.
  - Replace 'Argument' with 'Parameter' when referring to the identifiers of 
the macro definition (as opposed to the supplied arguments - MacroArgs - during 
the macro invocation).

This is in preparation for submitting patches for review to implement 
__VA_OPT__ which will otherwise just keep lengthening the HandleDefineDirective 
function and making it less comprehensible.

I will also directly update some extra clang tooling that is broken by the 
change from Argument to Parameter.

Hopefully the bots will stay appeased.

Thanks!

Modified:
cfe/trunk/include/clang/Lex/MacroInfo.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/CodeGen/MacroPPCallbacks.cpp
cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
cfe/trunk/lib/Lex/MacroArgs.cpp
cfe/trunk/lib/Lex/MacroInfo.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Lex/TokenLexer.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/unittests/Lex/LexerTest.cpp

Modified: cfe/trunk/include/clang/Lex/MacroInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=308190=308189=308190=diff
==
--- cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/trunk/include/clang/Lex/MacroInfo.h Mon Jul 17 10:18:43 2017
@@ -42,14 +42,14 @@ class MacroInfo {
 
   /// \brief The list of arguments for a function-like macro.
   ///
-  /// ArgumentList points to the first of NumArguments pointers.
+  /// ParameterList points to the first of NumParameters pointers.
   ///
   /// This can be empty, for, e.g. "#define X()".  In a C99-style variadic
   /// macro, this includes the \c __VA_ARGS__ identifier on the list.
-  IdentifierInfo **ArgumentList;
+  IdentifierInfo **ParameterList;
 
-  /// \see ArgumentList
-  unsigned NumArguments;
+  /// \see ParameterList
+  unsigned NumParameters;
 
   /// \brief This is the list of tokens that the macro is defined to.
   SmallVector ReplacementTokens;
@@ -153,37 +153,37 @@ public:
   /// \brief Set the value of the IsWarnIfUnused flag.
   void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
 
-  /// \brief Set the specified list of identifiers as the argument list for
+  /// \brief Set the specified list of identifiers as the parameter list for
   /// this macro.
-  void setArgumentList(ArrayRef List,
+  void setParameterList(ArrayRef List,
llvm::BumpPtrAllocator ) {
-assert(ArgumentList == nullptr && NumArguments == 0 &&
-   "Argument list already set!");
+assert(ParameterList == nullptr && NumParameters == 0 &&
+   "Parameter list already set!");
 if (List.empty())
   return;
 
-NumArguments = List.size();
-ArgumentList = PPAllocator.Allocate(List.size());
-std::copy(List.begin(), List.end(), ArgumentList);
+NumParameters = List.size();
+ParameterList = PPAllocator.Allocate(List.size());
+std::copy(List.begin(), List.end(), ParameterList);
   }
 
-  /// Arguments - The list of arguments for a function-like macro.  This can be
-  /// empty, for, e.g. "#define X()".
-  typedef IdentifierInfo *const *arg_iterator;
-  bool arg_empty() const { return NumArguments == 0; }
-  arg_iterator arg_begin() const { return ArgumentList; }
-  arg_iterator arg_end() const { return ArgumentList + NumArguments; }
-  unsigned getNumArgs() const { return NumArguments; }
-  ArrayRef args() const {
-return ArrayRef(ArgumentList, NumArguments);
+  /// Parameters - The list of parameters for a function-like macro.  This can 
+  /// be empty, for, e.g. "#define X()".
+  typedef IdentifierInfo *const *param_iterator;
+  bool param_empty() const { return NumParameters == 0; }
+  param_iterator param_begin() const { return ParameterList; }
+  param_iterator param_end() const { return ParameterList + NumParameters; }
+  unsigned getNumParams() const { return NumParameters; }
+  ArrayRef params() const {
+return ArrayRef(ParameterList, NumParameters);
   }
 
-  /// \brief Return the argument number of the specified identifier,
-  /// or -1 if the identifier is not a formal argument identifier.
-  int getArgumentNum(const IdentifierInfo *Arg) const {
-for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
+  /// \brief Return the parameter number of the specified identifier,
+  /// or -1 if the identifier is not a formal parameter identifier.
+  int getParameterNum(const IdentifierInfo 

r308158 - Revert changes from my previous refactoring - will need to fix dependencies in clang's extra tooling (such as clang-tidy etc.).

2017-07-16 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Jul 16 19:03:21 2017
New Revision: 308158

URL: http://llvm.org/viewvc/llvm-project?rev=308158=rev
Log:
Revert changes from my previous refactoring - will need to fix dependencies in 
clang's extra tooling (such as clang-tidy etc.).

Sorry about that.

Modified:
cfe/trunk/include/clang/Lex/MacroInfo.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/CodeGen/MacroPPCallbacks.cpp
cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
cfe/trunk/lib/Lex/MacroArgs.cpp
cfe/trunk/lib/Lex/MacroInfo.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Lex/TokenLexer.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/unittests/Lex/LexerTest.cpp

Modified: cfe/trunk/include/clang/Lex/MacroInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=308158=308157=308158=diff
==
--- cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/trunk/include/clang/Lex/MacroInfo.h Sun Jul 16 19:03:21 2017
@@ -42,14 +42,14 @@ class MacroInfo {
 
   /// \brief The list of arguments for a function-like macro.
   ///
-  /// ParameterList points to the first of NumParameters pointers.
+  /// ArgumentList points to the first of NumArguments pointers.
   ///
   /// This can be empty, for, e.g. "#define X()".  In a C99-style variadic
   /// macro, this includes the \c __VA_ARGS__ identifier on the list.
-  IdentifierInfo **ParameterList;
+  IdentifierInfo **ArgumentList;
 
-  /// \see ParameterList
-  unsigned NumParameters;
+  /// \see ArgumentList
+  unsigned NumArguments;
 
   /// \brief This is the list of tokens that the macro is defined to.
   SmallVector ReplacementTokens;
@@ -153,37 +153,37 @@ public:
   /// \brief Set the value of the IsWarnIfUnused flag.
   void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
 
-  /// \brief Set the specified list of identifiers as the parameter list for
+  /// \brief Set the specified list of identifiers as the argument list for
   /// this macro.
-  void setParameterList(ArrayRef List,
+  void setArgumentList(ArrayRef List,
llvm::BumpPtrAllocator ) {
-assert(ParameterList == nullptr && NumParameters == 0 &&
-   "Parameter list already set!");
+assert(ArgumentList == nullptr && NumArguments == 0 &&
+   "Argument list already set!");
 if (List.empty())
   return;
 
-NumParameters = List.size();
-ParameterList = PPAllocator.Allocate(List.size());
-std::copy(List.begin(), List.end(), ParameterList);
+NumArguments = List.size();
+ArgumentList = PPAllocator.Allocate(List.size());
+std::copy(List.begin(), List.end(), ArgumentList);
   }
 
-  /// Parameters - The list of parameters for a function-like macro.  This can 
-  /// be empty, for, e.g. "#define X()".
-  typedef IdentifierInfo *const *param_iterator;
-  bool param_empty() const { return NumParameters == 0; }
-  param_iterator param_begin() const { return ParameterList; }
-  param_iterator param_end() const { return ParameterList + NumParameters; }
-  unsigned getNumParams() const { return NumParameters; }
-  ArrayRef params() const {
-return ArrayRef(ParameterList, NumParameters);
+  /// Arguments - The list of arguments for a function-like macro.  This can be
+  /// empty, for, e.g. "#define X()".
+  typedef IdentifierInfo *const *arg_iterator;
+  bool arg_empty() const { return NumArguments == 0; }
+  arg_iterator arg_begin() const { return ArgumentList; }
+  arg_iterator arg_end() const { return ArgumentList + NumArguments; }
+  unsigned getNumArgs() const { return NumArguments; }
+  ArrayRef args() const {
+return ArrayRef(ArgumentList, NumArguments);
   }
 
-  /// \brief Return the parameter number of the specified identifier,
-  /// or -1 if the identifier is not a formal parameter identifier.
-  int getParameterNum(const IdentifierInfo *Arg) const {
-for (param_iterator I = param_begin(), E = param_end(); I != E; ++I)
+  /// \brief Return the argument number of the specified identifier,
+  /// or -1 if the identifier is not a formal argument identifier.
+  int getArgumentNum(const IdentifierInfo *Arg) const {
+for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
   if (*I == Arg)
-return I - param_begin();
+return I - arg_begin();
 return -1;
   }
 

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=308158=308157=308158=diff
==
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Sun Jul 16 19:03:21 2017
@@ -1813,24 

r308157 - [NFC] Refactor the Preprocessor function that handles Macro definitions and rename Arguments to Parameters in Macro Definitions.

2017-07-16 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Jul 16 18:27:53 2017
New Revision: 308157

URL: http://llvm.org/viewvc/llvm-project?rev=308157=rev
Log:
[NFC] Refactor the Preprocessor function that handles Macro definitions and 
rename Arguments to Parameters in Macro Definitions. 
  - Extracted the reading of the tokens out into a separate function.
  - Replace 'Argument' with 'Parameter' when referring to the identifiers of 
the macro definition (as opposed to the supplied arguments - MacroArgs - during 
the macro invocation).

This is in preparation for submitting patches for review to implement 
__VA_OPT__ which will otherwise just keep lengthening the HandleDefineDirective 
function and making it less comprehensible.


Thanks!

Modified:
cfe/trunk/include/clang/Lex/MacroInfo.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/CodeGen/MacroPPCallbacks.cpp
cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
cfe/trunk/lib/Lex/MacroArgs.cpp
cfe/trunk/lib/Lex/MacroInfo.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Lex/TokenLexer.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/unittests/Lex/LexerTest.cpp

Modified: cfe/trunk/include/clang/Lex/MacroInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=308157=308156=308157=diff
==
--- cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/trunk/include/clang/Lex/MacroInfo.h Sun Jul 16 18:27:53 2017
@@ -42,14 +42,14 @@ class MacroInfo {
 
   /// \brief The list of arguments for a function-like macro.
   ///
-  /// ArgumentList points to the first of NumArguments pointers.
+  /// ParameterList points to the first of NumParameters pointers.
   ///
   /// This can be empty, for, e.g. "#define X()".  In a C99-style variadic
   /// macro, this includes the \c __VA_ARGS__ identifier on the list.
-  IdentifierInfo **ArgumentList;
+  IdentifierInfo **ParameterList;
 
-  /// \see ArgumentList
-  unsigned NumArguments;
+  /// \see ParameterList
+  unsigned NumParameters;
 
   /// \brief This is the list of tokens that the macro is defined to.
   SmallVector ReplacementTokens;
@@ -153,37 +153,37 @@ public:
   /// \brief Set the value of the IsWarnIfUnused flag.
   void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
 
-  /// \brief Set the specified list of identifiers as the argument list for
+  /// \brief Set the specified list of identifiers as the parameter list for
   /// this macro.
-  void setArgumentList(ArrayRef List,
+  void setParameterList(ArrayRef List,
llvm::BumpPtrAllocator ) {
-assert(ArgumentList == nullptr && NumArguments == 0 &&
-   "Argument list already set!");
+assert(ParameterList == nullptr && NumParameters == 0 &&
+   "Parameter list already set!");
 if (List.empty())
   return;
 
-NumArguments = List.size();
-ArgumentList = PPAllocator.Allocate(List.size());
-std::copy(List.begin(), List.end(), ArgumentList);
+NumParameters = List.size();
+ParameterList = PPAllocator.Allocate(List.size());
+std::copy(List.begin(), List.end(), ParameterList);
   }
 
-  /// Arguments - The list of arguments for a function-like macro.  This can be
-  /// empty, for, e.g. "#define X()".
-  typedef IdentifierInfo *const *arg_iterator;
-  bool arg_empty() const { return NumArguments == 0; }
-  arg_iterator arg_begin() const { return ArgumentList; }
-  arg_iterator arg_end() const { return ArgumentList + NumArguments; }
-  unsigned getNumArgs() const { return NumArguments; }
-  ArrayRef args() const {
-return ArrayRef(ArgumentList, NumArguments);
+  /// Parameters - The list of parameters for a function-like macro.  This can 
+  /// be empty, for, e.g. "#define X()".
+  typedef IdentifierInfo *const *param_iterator;
+  bool param_empty() const { return NumParameters == 0; }
+  param_iterator param_begin() const { return ParameterList; }
+  param_iterator param_end() const { return ParameterList + NumParameters; }
+  unsigned getNumParams() const { return NumParameters; }
+  ArrayRef params() const {
+return ArrayRef(ParameterList, NumParameters);
   }
 
-  /// \brief Return the argument number of the specified identifier,
-  /// or -1 if the identifier is not a formal argument identifier.
-  int getArgumentNum(const IdentifierInfo *Arg) const {
-for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
+  /// \brief Return the parameter number of the specified identifier,
+  /// or -1 if the identifier is not a formal parameter identifier.
+  int getParameterNum(const IdentifierInfo *Arg) const {
+for (param_iterator I = param_begin(), E = param_end(); I != E; ++I)
   if (*I == Arg)
-return I - arg_begin();
+

r308118 - [c++2a] Add option -std=c++2a to enable support for potential/transitional C++2a features

2017-07-15 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Jul 15 17:23:04 2017
New Revision: 308118

URL: http://llvm.org/viewvc/llvm-project?rev=308118=rev
Log:
[c++2a] Add option -std=c++2a to enable support for potential/transitional 
C++2a features

- as usual C++2a implies all the C++'s that came before it.

Thank you Aaron for the feedback here: https://reviews.llvm.org/D35454 

Modified:
cfe/trunk/include/clang/Basic/LangOptions.def
cfe/trunk/include/clang/Frontend/LangStandard.h
cfe/trunk/include/clang/Frontend/LangStandards.def
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/Frontend/InitPreprocessor.cpp
cfe/trunk/test/Driver/std.cpp
cfe/trunk/test/Driver/unknown-std.cpp
cfe/trunk/test/Preprocessor/init.c

Modified: cfe/trunk/include/clang/Basic/LangOptions.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=308118=308117=308118=diff
==
--- cfe/trunk/include/clang/Basic/LangOptions.def (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.def Sat Jul 15 17:23:04 2017
@@ -90,6 +90,7 @@ LANGOPT(CPlusPlus , 1, 0, "C++")
 LANGOPT(CPlusPlus11   , 1, 0, "C++11")
 LANGOPT(CPlusPlus14   , 1, 0, "C++14")
 LANGOPT(CPlusPlus1z   , 1, 0, "C++1z")
+LANGOPT(CPlusPlus2a   , 1, 0, "C++2a")
 LANGOPT(ObjC1 , 1, 0, "Objective-C 1")
 LANGOPT(ObjC2 , 1, 0, "Objective-C 2")
 BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,

Modified: cfe/trunk/include/clang/Frontend/LangStandard.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/LangStandard.h?rev=308118=308117=308118=diff
==
--- cfe/trunk/include/clang/Frontend/LangStandard.h (original)
+++ cfe/trunk/include/clang/Frontend/LangStandard.h Sat Jul 15 17:23:04 2017
@@ -26,11 +26,12 @@ enum LangFeatures {
   CPlusPlus11 = (1 << 4),
   CPlusPlus14 = (1 << 5),
   CPlusPlus1z = (1 << 6),
-  Digraphs = (1 << 7),
-  GNUMode = (1 << 8),
-  HexFloat = (1 << 9),
-  ImplicitInt = (1 << 10),
-  OpenCL = (1 << 11)
+  CPlusPlus2a = (1 << 7),
+  Digraphs = (1 << 8),
+  GNUMode = (1 << 9),
+  HexFloat = (1 << 10),
+  ImplicitInt = (1 << 11),
+  OpenCL = (1 << 12)
 };
 
 }
@@ -81,6 +82,10 @@ public:
   /// isCPlusPlus1z - Language is a C++17 variant (or later).
   bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; }
 
+  /// isCPlusPlus2a - Language is a post-C++17 variant (or later).
+  bool isCPlusPlus2a() const { return Flags & frontend::CPlusPlus2a; }
+
+
   /// hasDigraphs - Language supports digraphs.
   bool hasDigraphs() const { return Flags & frontend::Digraphs; }
 

Modified: cfe/trunk/include/clang/Frontend/LangStandards.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/LangStandards.def?rev=308118=308117=308118=diff
==
--- cfe/trunk/include/clang/Frontend/LangStandards.def (original)
+++ cfe/trunk/include/clang/Frontend/LangStandards.def Sat Jul 15 17:23:04 2017
@@ -119,6 +119,16 @@ LANGSTANDARD(gnucxx1z, "gnu++1z",
  LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z 
|
  Digraphs | HexFloat | GNUMode)
 
+LANGSTANDARD(cxx2a, "c++2a",
+ CXX, "Working draft for ISO C++ 2020",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z 
|
+ CPlusPlus2a | Digraphs | HexFloat)
+
+LANGSTANDARD(gnucxx2a, "gnu++2a",
+ CXX, "Working draft for ISO C++ 2020 with GNU extensions",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z 
|
+ CPlusPlus2a | Digraphs | HexFloat | GNUMode)
+
 // OpenCL
 LANGSTANDARD(opencl10, "cl1.0",
  OpenCL, "OpenCL 1.0",

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=308118=308117=308118=diff
==
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Sat Jul 15 17:23:04 2017
@@ -1683,6 +1683,7 @@ void CompilerInvocation::setLangDefaults
   Opts.CPlusPlus11 = Std.isCPlusPlus11();
   Opts.CPlusPlus14 = Std.isCPlusPlus14();
   Opts.CPlusPlus1z = Std.isCPlusPlus1z();
+  Opts.CPlusPlus2a = Std.isCPlusPlus2a();
   Opts.Digraphs = Std.hasDigraphs();
   Opts.GNUMode = Std.isGNUMode();
   Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus;

Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=308118=308117=308118=diff
==
--- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original)
+++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Sat Jul 

r303492 - Fix PR25627: constant expressions being odr-used in template arguments.

2017-05-20 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat May 20 14:58:04 2017
New Revision: 303492

URL: http://llvm.org/viewvc/llvm-project?rev=303492=rev
Log:
Fix PR25627: constant expressions being odr-used in template arguments.

This patch ensures that clang processes the expression-nodes that are generated 
when disambiguating between types and expressions within template arguments as 
constant-expressions by installing the ConstantEvaluated 
ExpressionEvaluationContext just before attempting the disambiguation - and 
then making sure that Context carries through into ParseConstantExpression (by 
refactoring it out into a function that does not create its own 
EvaluationContext: ParseConstantExpressionInExprEvalContext) 

Note, prior to this patch, trunk would correctly disambiguate and identify the 
expression as an expression - and while it would annotate the token with the 
expression - it would fail to complete the odr-use processing (specifically, 
failing to trigger Sema::UpdateMarkingForLValueToRValue as is done for all 
Constant Expressions, which would remove it from being considered odr-used).  
By installing the ConstantExpression Evaluation Context prior to 
disambiguation, and making sure it carries though, we ensure correct processing 
of the expression-node.

For e.g:
  template struct X { };
  void f() {
const int N = 10;
X x; // should be OK.
[] { return X{}; }; // Should be OK - no capture - but clang errors!
  }

See a related bug: https://bugs.llvm.org//show_bug.cgi?id=25627

In summary (and reiteration), the fix is as follows:

- Remove the EnteredConstantEvaluatedContext action from 
ParseTemplateArgumentList (relying on ParseTemplateArgument getting it right)
- Add the EnteredConstantEvaluatedContext action just prior to undergoing 
the disambiguating parse, and if the parse succeeds for an expression, carry 
the context though into a refactored version of ParseConstantExpression that 
does not create its own ExpressionEvaluationContext.

See https://reviews.llvm.org/D31588 for additional context regarding some of 
the more fragile and complicated approaches attempted, and Richard's feedback 
that eventually shaped the simpler and more robust rendition that is being 
committed.

Thanks Richard!

Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/test/SemaCXX/lambda-expressions.cpp
cfe/trunk/test/SemaCXX/local-classes.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=303492=303491=303492=diff
==
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat May 20 14:58:04 2017
@@ -1460,6 +1460,7 @@ public:
   };
 
   ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast);
+  ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState 
isTypeCast);
   ExprResult ParseConstantExpression(TypeCastState isTypeCast = NotTypeCast);
   ExprResult ParseConstraintExpression();
   // Expr that doesn't include commas.

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=303492=303491=303492=diff
==
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Sat May 20 14:58:04 2017
@@ -192,6 +192,16 @@ Parser::ParseAssignmentExprWithObjCMessa
   return ParseRHSOfBinaryExpression(R, prec::Assignment);
 }
 
+ExprResult
+Parser::ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast) {
+  assert(Actions.ExprEvalContexts.back().Context ==
+ Sema::ExpressionEvaluationContext::ConstantEvaluated &&
+ "Call this function only if your ExpressionEvaluationContext is "
+ "already ConstantEvaluated");
+  ExprResult LHS(ParseCastExpression(false, false, isTypeCast));
+  ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+  return Actions.ActOnConstantExpression(Res);
+}
 
 ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
   // C++03 [basic.def.odr]p2:
@@ -200,10 +210,7 @@ ExprResult Parser::ParseConstantExpressi
   // C++98 and C++11 have no such rule, but this is only a defect in C++98.
   EnterExpressionEvaluationContext ConstantEvaluated(
   Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
-
-  ExprResult LHS(ParseCastExpression(false, false, isTypeCast));
-  ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
-  return Actions.ActOnConstantExpression(Res);
+  return ParseConstantExpressionInExprEvalContext(isTypeCast);
 }
 
 /// \brief Parse a constraint-expression.

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: 

r303030 - Silence buildbots by tweaking an IR codegen test to be less specific w register names.

2017-05-14 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun May 14 21:56:02 2017
New Revision: 303030

URL: http://llvm.org/viewvc/llvm-project?rev=303030=rev
Log:
Silence buildbots by tweaking an IR codegen test to be less specific w register 
names.

Modified:
cfe/trunk/test/CodeGenCXX/vla.cpp

Modified: cfe/trunk/test/CodeGenCXX/vla.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vla.cpp?rev=303030=303029=303030=diff
==
--- cfe/trunk/test/CodeGenCXX/vla.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vla.cpp Sun May 14 21:56:02 2017
@@ -104,7 +104,7 @@ void test3(int b, int c) {
   //CHECK-NEXT: [[VLA_SIZEOF_DIM2:%.*]] = mul nuw i64 4, [[VLA_DIM2_PRE]]
   //CHECK-NEXT: [[VLA_NUM_ELEMENTS:%.*]] = udiv i64 [[VLA_SIZEOF]], 
[[VLA_SIZEOF_DIM2]]
   //CHECK-NEXT: [[VLA_END_INDEX:%.*]] = mul nsw i64 [[VLA_NUM_ELEMENTS]], 
[[VLA_DIM2_PRE]]
-  //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* %7, i64 
[[VLA_END_INDEX]]
+  //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* 
{{%.*}}, i64 [[VLA_END_INDEX]]
   //CHECK-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
  
   for (auto  : varr) 0;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303027 - [NFC] Remove some comments (IR aid) from a test file erroneous committed in r303026

2017-05-14 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun May 14 20:54:02 2017
New Revision: 303027

URL: http://llvm.org/viewvc/llvm-project?rev=303027=rev
Log:
[NFC] Remove some comments (IR aid) from a test file erroneous committed in 
r303026

Modified:
cfe/trunk/test/CodeGenCXX/vla.cpp

Modified: cfe/trunk/test/CodeGenCXX/vla.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vla.cpp?rev=303027=303026=303027=diff
==
--- cfe/trunk/test/CodeGenCXX/vla.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vla.cpp Sun May 14 20:54:02 2017
@@ -79,32 +79,6 @@ void test2(int b) {
   for (int d : varr) 0;
 }
 
-#if 0
-  %0 = load i32, i32* %b.addr, align 4
-  %1 = zext i32 %0 to i64
-  %2 = load i32, i32* %c.addr, align 4
-  %3 = zext i32 %2 to i64
-  %4 = call i8* @llvm.stacksave()
-  store i8* %4, i8** %saved_stack, align 8
-  %5 = mul nuw i64 %1, %3
-  %vla = alloca i32, i64 %5, align 16
-  store i32 15, i32* %c.addr, align 4
-  store i32 15, i32* %b.addr, align 4
-  store i32* %vla, i32** %__range, align 8
-
-
-  %6 = load i32*, i32** %__range, align 8
-  store i32* %6, i32** %__begin, align 8
-  %7 = load i32*, i32** %__range, align 8
-  %8 = mul nuw i64 %1, %3
-  %9 = mul nuw i64 4, %8
-  %10 = mul nuw i64 4, %3
-  %div = udiv i64 %9, %10
-  %vla.index = mul nsw i64 %div, %3
-  %add.ptr = getelementptr inbounds i32, i32* %7, i64 %vla.index
-  store i32* %add.ptr, i32** %__end, align 8
-#endif
-
 void test3(int b, int c) {
   // CHECK-LABEL: define void {{.*}}test3{{.*}}(i32 %b, i32 %c)
   int varr[b][c];


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r303026 - Fix PR32933: crash on lambda capture of VLA

2017-05-14 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun May 14 20:49:19 2017
New Revision: 303026

URL: http://llvm.org/viewvc/llvm-project?rev=303026=rev
Log:
Fix PR32933: crash on lambda capture of VLA

https://bugs.llvm.org/show_bug.cgi?id=32933

Turns out clang wasn't really handling vla's (*) in C++11's for-range entirely 
correctly. 

For e.g. This would lead to generation of buggy IR:

  void foo(int b) {
int vla[b];
b = -1;  // This store would affect the '__end = vla + b'
for (int  : vla) 
  c = 0;
  }

Additionally, code-gen would get confused when VLA's were reference-captured by 
lambdas, and then used in a for-range, which would result in an attempt to 
generate IR for '__end = vla + b' within the lambda's body - without any 
capture of 'b' - hence the assertion.

This patch modifies clang, so that for VLA's it translates the end pointer 
approximately into:
  __end = __begin + sizeof(vla)/sizeof(vla->getElementType())

As opposed to the __end = __begin + b;

I considered passing a magic value into codegen - or having codegen special 
case the '__end' variable when it referred to a variably-modified type, but I 
decided against that approach, because it smelled like I would be increasing a 
complicated form of coupling, that I think would be even harder to maintain 
than the above approach (which can easily be optimized (-O1) to refer to the 
run-time bound that was calculated upon array's creation or copied into the 
lambda's closure object).


(*) why oh why gcc would you enable this by default?! ;)

Modified:
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/test/CodeGenCXX/vla.cpp
cfe/trunk/test/SemaCXX/for-range-examples.cpp

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=303026=303025=303026=diff
==
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Sun May 14 20:49:19 2017
@@ -2268,9 +2268,57 @@ Sema::BuildCXXForRangeStmt(SourceLocatio
 BoundExpr = IntegerLiteral::Create(
 Context, CAT->getSize(), Context.getPointerDiffType(), RangeLoc);
   else if (const VariableArrayType *VAT =
-   dyn_cast(UnqAT))
-BoundExpr = VAT->getSizeExpr();
-  else {
+   dyn_cast(UnqAT)) {
+// For a variably modified type we can't just use the expression within
+// the array bounds, since we don't want that to be re-evaluated here.
+// Rather, we need to determine what it was when the array was first
+// created - so we resort to using sizeof(vla)/sizeof(element).
+// For e.g.
+//  void f(int b) { 
+//int vla[b];
+//b = -1;   <-- This should not affect the num of iterations below
+//for (int  : vla) { .. }
+//  }
+
+// FIXME: This results in codegen generating IR that recalculates the
+// run-time number of elements (as opposed to just using the IR Value
+// that corresponds to the run-time value of each bound that was
+// generated when the array was created.) If this proves too 
embarassing
+// even for unoptimized IR, consider passing a magic-value/cookie to
+// codegen that then knows to simply use that initial llvm::Value (that
+// corresponds to the bound at time of array creation) within
+// getelementptr.  But be prepared to pay the price of increasing a
+// customized form of coupling between the two components - which  
could
+// be hard to maintain as the codebase evolves.
+
+ExprResult SizeOfVLAExprR = ActOnUnaryExprOrTypeTraitExpr(
+EndVar->getLocation(), UETT_SizeOf,
+/*isType=*/true,
+CreateParsedType(VAT->desugar(), Context.getTrivialTypeSourceInfo(
+ VAT->desugar(), RangeLoc))
+.getAsOpaquePtr(),
+EndVar->getSourceRange());
+if (SizeOfVLAExprR.isInvalid())
+  return StmtError();
+
+ExprResult SizeOfEachElementExprR = ActOnUnaryExprOrTypeTraitExpr(
+EndVar->getLocation(), UETT_SizeOf,
+/*isType=*/true,
+CreateParsedType(VAT->desugar(),
+ Context.getTrivialTypeSourceInfo(
+ VAT->getElementType(), RangeLoc))
+.getAsOpaquePtr(),
+EndVar->getSourceRange());
+if (SizeOfEachElementExprR.isInvalid())
+  return StmtError();
+
+BoundExpr =
+ActOnBinOp(S, EndVar->getLocation(), tok::slash,
+   SizeOfVLAExprR.get(), SizeOfEachElementExprR.get());
+if (BoundExpr.isInvalid())
+  return StmtError();
+
+  } else {
 // Can't be a DependentSizedArrayType or an IncompleteArrayType since
 // UnqAT is not incomplete and Range is not type-dependent.
  

r302507 - Fix PR32638 : Make sure we switch Sema's CurContext to the substituted FunctionDecl when instantiating the exception specification.

2017-05-08 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon May  8 23:17:15 2017
New Revision: 302507

URL: http://llvm.org/viewvc/llvm-project?rev=302507=rev
Log:
Fix PR32638 : Make sure we switch Sema's CurContext to the substituted 
FunctionDecl when instantiating the exception specification.

This fixes the bug: https://bugs.llvm.org/show_bug.cgi?id=32638

  int main()
  {
[](auto x) noexcept(noexcept(x)) { } (0);
  }

In the above code, prior to this patch, when substituting into the noexcept 
expression, i.e. transforming the DeclRefExpr that represents 'x' - clang 
attempts to capture 'x' because Sema's CurContext is still pointing to the 
pattern FunctionDecl (i.e. the templated-decl set in 
FinishTemplateArgumentDeduction) which does not match the substituted 'x's 
DeclContext, which leads to an attempt to capture and an assertion failure.  

We fix this by adjusting Sema's CurContext to point to the substituted 
FunctionDecl under which the noexcept specifier's argument should be 
transformed, and so the ParmVarDecl that 'x' refers to has the same declcontext 
and no capture is attempted. 

I briefly investigated whether the SwitchContext should occur right after 
VisitMethodDecl creates the new substituted FunctionDecl, instead of only 
during instantiating the exception specification - but seeing no other code 
that seemed to rely on that, I decided to leave it just for the duration of the 
exception specification instantiation.


Modified:
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=302507=302506=302507=diff
==
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon May  8 23:17:15 2017
@@ -3660,6 +3660,7 @@ TemplateDeclInstantiator::InitFunctionIn
   New->setType(SemaRef.Context.getFunctionType(
   NewProto->getReturnType(), NewProto->getParamTypes(), EPI));
 } else {
+  Sema::ContextRAII SwitchContext(SemaRef, New);
   SemaRef.SubstExceptionSpec(New, Proto, TemplateArgs);
 }
   }

Modified: cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp?rev=302507=302506=302507=diff
==
--- cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp Mon May  8 23:17:15 2017
@@ -986,3 +986,10 @@ class Enclosing3 {
   );
 };
 }
+
+namespace PR32638 {
+ //https://bugs.llvm.org/show_bug.cgi?id=32638
+ void test() {
+[](auto x) noexcept(noexcept(x)) { } (0);
+ }
+}
\ No newline at end of file


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r301973 - [NFC] Add original test that triggered crash post r301735

2017-05-02 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Tue May  2 16:02:46 2017
New Revision: 301973

URL: http://llvm.org/viewvc/llvm-project?rev=301973=rev
Log:
[NFC] Add original test that triggered crash post r301735 
- this is added just for completeness sake (though the general case should be 
represented by the test added in the revision to that patch:  
https://reviews.llvm.org/rL301972 )

Modified:
cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp

Modified: cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp?rev=301973=301972=301973=diff
==
--- cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp Tue May  2 16:02:46 
2017
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
 // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++98 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 %s -D CPP11
 
 #define LOCKABLE__attribute__ ((lockable))
 #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
@@ -1513,3 +1513,15 @@ public:
 
 }  // end namespace FunctionAttributesInsideClass_ICE_Test
 
+
+#ifdef CPP11
+namespace CRASH_POST_R301735 {
+  class SomeClass {
+   public:
+ void foo() {
+   auto l = [this] { auto l = [] () EXCLUSIVE_LOCKS_REQUIRED(mu_) {}; };
+ }
+ Mutex mu_;
+   };
+}
+#endif
\ No newline at end of file


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r301972 - Fix PR32831 (Try Again): 'this' capture while instantiating generic lambda call operator specialization

2017-05-02 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Tue May  2 15:56:34 2017
New Revision: 301972

URL: http://llvm.org/viewvc/llvm-project?rev=301972=rev
Log:
Fix PR32831 (Try Again): 'this' capture while instantiating generic lambda call 
operator specialization

When computing the appropriate cv-qualifiers for the 'this' capture, we have to 
examine each enclosing lambda - but when using the FunctionScopeInfo stack we 
have to ensure that the lambda below (outer) is the decl-context of the 
closure-class of the current lambda.

https://bugs.llvm.org/show_bug.cgi?id=32831

This patch was initially committed here: https://reviews.llvm.org/rL301735
Then reverted here: https://reviews.llvm.org/rL301916

The issue with the original patch was a failure to check that the closure type 
has been created within the LambdaScopeInfo before querying its DeclContext - 
instead of just assuming it has (silly!).  A reduced example such as this 
highlights the problem:
  struct X {
 int data;
 auto foo() { return [] { return [] -> decltype(data) { return 0; }; }; }
  };

When 'data' within decltype(data) tries to determine the type of 'this', none 
of the LambdaScopeInfo's have their closure types created at that point.

 

Modified:
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/cxx1z-lambda-star-this.cpp

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=301972=301971=301972=diff
==
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue May  2 15:56:34 2017
@@ -901,17 +901,36 @@ static QualType adjustCVQualifiersForCXX
   // capturing lamdbda's call operator.
   //
 
-  // The issue is that we cannot rely entirely on the FunctionScopeInfo stack
-  // since ScopeInfos are pushed on during parsing and treetransforming. But
-  // since a generic lambda's call operator can be instantiated anywhere (even
-  // end of the TU) we need to be able to examine its enclosing lambdas and so
-  // we use the DeclContext to get a hold of the closure-class and query it for
-  // capture information.  The reason we don't just resort to always using the
-  // DeclContext chain is that it is only mature for lambda expressions
-  // enclosing generic lambda's call operators that are being instantiated.
+  // Since the FunctionScopeInfo stack is representative of the lexical
+  // nesting of the lambda expressions during initial parsing (and is the best
+  // place for querying information about captures about lambdas that are
+  // partially processed) and perhaps during instantiation of function 
templates
+  // that contain lambda expressions that need to be transformed BUT not
+  // necessarily during instantiation of a nested generic lambda's function 
call
+  // operator (which might even be instantiated at the end of the TU) - at 
which
+  // time the DeclContext tree is mature enough to query capture information
+  // reliably - we use a two pronged approach to walk through all the lexically
+  // enclosing lambda expressions:
+  //
+  //  1) Climb down the FunctionScopeInfo stack as long as each item represents
+  //  a Lambda (i.e. LambdaScopeInfo) AND each LSI's 'closure-type' is 
lexically
+  //  enclosed by the call-operator of the LSI below it on the stack (while
+  //  tracking the enclosing DC for step 2 if needed).  Note the topmost LSI on
+  //  the stack represents the innermost lambda.
+  //
+  //  2) If we run out of enclosing LSI's, check if the enclosing DeclContext
+  //  represents a lambda's call operator.  If it does, we must be 
instantiating
+  //  a generic lambda's call operator (represented by the Current LSI, and
+  //  should be the only scenario where an inconsistency between the LSI and 
the
+  //  DeclContext should occur), so climb out the DeclContexts if they
+  //  represent lambdas, while querying the corresponding closure types
+  //  regarding capture information.
 
+  // 1) Climb down the function scope info stack.
   for (int I = FunctionScopes.size();
-   I-- && isa(FunctionScopes[I]);
+   I-- && isa(FunctionScopes[I]) &&
+   (!CurLSI || !CurLSI->Lambda || CurLSI->Lambda->getDeclContext() ==
+   cast(FunctionScopes[I])->CallOperator);
CurDC = getLambdaAwareParentOfDeclContext(CurDC)) {
 CurLSI = cast(FunctionScopes[I]);
 
@@ -927,11 +946,17 @@ static QualType adjustCVQualifiersForCXX
   return ASTCtx.getPointerType(ClassType);
 }
   }
-  // We've run out of ScopeInfos but check if CurDC is a lambda (which can
-  // happen during instantiation of generic lambdas)
+
+  // 2) We've run out of ScopeInfos but check if CurDC is a lambda (which can
+  // happen during instantiation of its nested generic lambda call operator)
   if (isLambdaCallOperator(CurDC)) {
-assert(CurLSI);
-assert(isGenericLambdaCallOperatorSpecialization(CurLSI->CallOperator));
+

r301735 - Fix PR32831: 'this capture while instantiating generic lambda call operator specialization

2017-04-28 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Fri Apr 28 22:49:17 2017
New Revision: 301735

URL: http://llvm.org/viewvc/llvm-project?rev=301735=rev
Log:
Fix PR32831: 'this capture while instantiating generic lambda call operator 
specialization

When computing the appropriate cv-qualifiers for the 'this' capture, we have to 
examine each enclosing lambda - but when using the FunctionScopeInfo stack we 
have to ensure that the lambda below (outer) is the decl-context of the 
closure-class of the current lambda.

https://bugs.llvm.org/show_bug.cgi?id=32831

Modified:
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/cxx1z-lambda-star-this.cpp

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=301735=301734=301735=diff
==
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Apr 28 22:49:17 2017
@@ -901,17 +901,35 @@ static QualType adjustCVQualifiersForCXX
   // capturing lamdbda's call operator.
   //
 
-  // The issue is that we cannot rely entirely on the FunctionScopeInfo stack
-  // since ScopeInfos are pushed on during parsing and treetransforming. But
-  // since a generic lambda's call operator can be instantiated anywhere (even
-  // end of the TU) we need to be able to examine its enclosing lambdas and so
-  // we use the DeclContext to get a hold of the closure-class and query it for
-  // capture information.  The reason we don't just resort to always using the
-  // DeclContext chain is that it is only mature for lambda expressions
-  // enclosing generic lambda's call operators that are being instantiated.
+  // Since the FunctionScopeInfo stack is representative of the lexical
+  // nesting of the lambda expressions during initial parsing (and is the best
+  // place for querying information about captures about lambdas that are
+  // partially processed) and perhaps during instantiation of function 
templates
+  // that contain lambda expressions that need to be transformed BUT not
+  // necessarily during instantiation of a nested generic lambda's function 
call
+  // operator (which might even be instantiated at the end of the TU) - at 
which
+  // time the DeclContext tree is mature enough to query capture information
+  // reliably - we use a two pronged approach to walk through all the lexically
+  // enclosing lambda expressions:
+  //
+  //  1) Climb down the FunctionScopeInfo stack as long as each item represents
+  //  a Lambda (i.e. LambdaScopeInfo) AND each LSI's 'closure-type' is 
lexically
+  //  enclosed by the call-operator of the LSI below it on the stack (while
+  //  tracking the enclosing DC for step 2 if needed).  Note the topmost LSI on
+  //  the stack represents the innermost lambda.
+  //
+  //  2) Iterate out through the DeclContext chain (if it represents a lambda's
+  //  call operator, and therefore must be a generic lambda's call operator,
+  //  which is the only time an inconsistency between the LSI and the
+  //  DeclContext should occur) querying closure types regarding capture
+  //  information.
 
+
+  // 1) Climb down the function scope info stack.
   for (int I = FunctionScopes.size();
-   I-- && isa(FunctionScopes[I]);
+   I-- && isa(FunctionScopes[I]) &&
+   (!CurLSI || CurLSI->Lambda->getDeclContext() ==
+   cast(FunctionScopes[I])->CallOperator);
CurDC = getLambdaAwareParentOfDeclContext(CurDC)) {
 CurLSI = cast(FunctionScopes[I]);
 
@@ -927,11 +945,17 @@ static QualType adjustCVQualifiersForCXX
   return ASTCtx.getPointerType(ClassType);
 }
   }
-  // We've run out of ScopeInfos but check if CurDC is a lambda (which can
-  // happen during instantiation of generic lambdas)
+
+  // 2) We've run out of ScopeInfos but check if CurDC is a lambda (which can
+  // happen during instantiation of its nested generic lambda call operator)
   if (isLambdaCallOperator(CurDC)) {
-assert(CurLSI);
-assert(isGenericLambdaCallOperatorSpecialization(CurLSI->CallOperator));
+assert(CurLSI && "While computing 'this' capture-type for a generic "
+ "lambda, we must have a corresponding LambdaScopeInfo");
+assert(isGenericLambdaCallOperatorSpecialization(CurLSI->CallOperator) &&
+   "While computing 'this' capture-type for a generic lambda, when we "
+   "run out of enclosing LSI's, yet the enclosing DC is a "
+   "lambda-call-operator we must be (i.e. Current LSI) in a generic "
+   "lambda call oeprator");
 assert(CurDC == getLambdaAwareParentOfDeclContext(CurLSI->CallOperator));
 
 auto IsThisCaptured =

Modified: cfe/trunk/test/SemaCXX/cxx1z-lambda-star-this.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-lambda-star-this.cpp?rev=301735=301734=301735=diff
==
--- 

r299316 - [NFC, Scoped Enum] Convert Sema::ExpressionEvaluationContext into a scoped Enum

2017-04-01 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Apr  1 16:30:49 2017
New Revision: 299316

URL: http://llvm.org/viewvc/llvm-project?rev=299316=rev
Log:
[NFC, Scoped Enum] Convert Sema::ExpressionEvaluationContext into a scoped Enum

- also replace direct equality checks against the ConstantEvaluated enumerator  
with isConstantEvaluted(), in anticipation of adding finer granularity to the 
various ConstantEvaluated contexts and reinstating certain restrictions on 
where lambda expressions can occur in C++17.

- update the clang tablegen backend that uses these Enumerators, and add the 
relevant scope where needed.

Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaExprMember.cpp
cfe/trunk/lib/Sema/SemaLambda.cpp
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/lib/Sema/SemaStmtAsm.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=299316=299315=299316=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sat Apr  1 16:30:49 2017
@@ -681,7 +681,8 @@ public:
   : S(S), SavedContext(S, DC)
 {
   S.PushFunctionScope();
-  S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
+  S.PushExpressionEvaluationContext(
+  Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
 }
 
 ~SynthesizedFunctionScope() {
@@ -802,7 +803,7 @@ public:
 
   /// \brief Describes how the expressions currently being parsed are
   /// evaluated at run-time, if at all.
-  enum ExpressionEvaluationContext {
+  enum class ExpressionEvaluationContext {
 /// \brief The current expression and its subexpressions occur within an
 /// unevaluated operand (C++11 [expr]p7), such as the subexpression of
 /// \c sizeof, where the type of the expression may be significant but
@@ -908,8 +909,12 @@ public:
 MangleNumberingContext (ASTContext );
 
 bool isUnevaluated() const {
-  return Context == Unevaluated || Context == UnevaluatedAbstract ||
- Context == UnevaluatedList;
+  return Context == ExpressionEvaluationContext::Unevaluated ||
+ Context == ExpressionEvaluationContext::UnevaluatedAbstract ||
+ Context == ExpressionEvaluationContext::UnevaluatedList;
+}
+bool isConstantEvaluated() const {
+  return Context == ExpressionEvaluationContext::ConstantEvaluated;
 }
   };
 
@@ -10315,6 +10320,7 @@ class EnterExpressionEvaluationContext {
   bool Entered = true;
 
 public:
+
   EnterExpressionEvaluationContext(Sema ,
Sema::ExpressionEvaluationContext 
NewContext,
Decl *LambdaContextDecl = nullptr,
@@ -10345,8 +10351,8 @@ public:
 // a context.
 if (ShouldEnter && Actions.isUnevaluatedContext() &&
 Actions.getLangOpts().CPlusPlus11) {
-  Actions.PushExpressionEvaluationContext(Sema::UnevaluatedList, nullptr,
-  false);
+  Actions.PushExpressionEvaluationContext(
+  Sema::ExpressionEvaluationContext::UnevaluatedList, nullptr, false);
   Entered = true;
 }
   }

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=299316=299315=299316=diff
==
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Sat Apr  1 16:30:49 2017
@@ -344,9 +344,9 @@ void Parser::ParseLexedMethodDeclaration
 
   // The argument isn't actually potentially evaluated unless it is
   // used.
-  EnterExpressionEvaluationContext Eval(Actions,
-Sema::PotentiallyEvaluatedIfUsed,
-Param);
+  EnterExpressionEvaluationContext Eval(
+  Actions,
+  Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, 
Param);
 
   ExprResult 

Re: r295279 - [cxx1z-constexpr-lambda] Implement captures - thus completing implementation of constexpr lambdas.

2017-02-16 Thread Faisal Vali via cfe-commits
Of course Richard - I'll be happy to bump that value for C++1z
hopefully later today.
Thanks!
Faisal Vali



On Wed, Feb 15, 2017 at 10:30 PM, Richard Smith <rich...@metafoo.co.uk> wrote:
> On 15 February 2017 at 20:12, Faisal Vali via cfe-commits
> <cfe-commits@lists.llvm.org> wrote:
>>
>> Author: faisalv
>> Date: Wed Feb 15 22:12:21 2017
>> New Revision: 295279
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=295279=rev
>> Log:
>> [cxx1z-constexpr-lambda] Implement captures - thus completing
>> implementation of constexpr lambdas.
>>
>> Enable evaluation of captures within constexpr lambdas by using a strategy
>> similar to that used in CodeGen:
>>   - when starting evaluation of a lambda's call operator, create a map
>> from VarDecl's to a closure's FieldDecls
>>   - every time a VarDecl (or '*this) that represents a capture is
>> encountered while evaluating the expression via the expression evaluator
>> (specifically the LValueEvaluator) in ExprConstant.cpp - it is replaced by
>> the corresponding FieldDecl LValue (an Lvalue-to-Rvalue conversion on this
>> LValue representation then determines the right rvalue when needed).
>>
>> Thanks to Richard Smith and Hubert Tong for their review and feedback!
>
>
> Awesome, thanks Faisal!
>
> Want to bump our value for __cpp_constexpr to 201603 in C++1z mode to
> advertise support for this?
>
>>
>> https://reviews.llvm.org/D29748
>>
>>
>> Modified:
>> cfe/trunk/lib/AST/ExprConstant.cpp
>> cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
>>
>> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=295279=295278=295279=diff
>>
>> ==
>> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
>> +++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Feb 15 22:12:21 2017
>> @@ -425,6 +425,17 @@ namespace {
>>  /// Index - The call index of this call.
>>  unsigned Index;
>>
>> +// FIXME: Adding this to every 'CallStackFrame' may have a nontrivial
>> impact
>> +// on the overall stack usage of deeply-recursing constexpr
>> evaluataions.
>> +// (We should cache this map rather than recomputing it repeatedly.)
>> +// But let's try this and see how it goes; we can look into caching
>> the map
>> +// as a later change.
>> +
>> +/// LambdaCaptureFields - Mapping from captured variables/this to
>> +/// corresponding data members in the closure class.
>> +llvm::DenseMap LambdaCaptureFields;
>> +FieldDecl *LambdaThisCaptureField;
>> +
>>  CallStackFrame(EvalInfo , SourceLocation CallLoc,
>> const FunctionDecl *Callee, const LValue *This,
>> APValue *Arguments);
>> @@ -2279,6 +2290,10 @@ static bool HandleLValueComplexElement(E
>>return true;
>>  }
>>
>> +static bool handleLValueToRValueConversion(EvalInfo , const Expr
>> *Conv,
>> +   QualType Type, const LValue
>> ,
>> +   APValue );
>> +
>>  /// Try to evaluate the initializer for a variable declaration.
>>  ///
>>  /// \param Info   Information about the ongoing evaluation.
>> @@ -2290,6 +2305,7 @@ static bool HandleLValueComplexElement(E
>>  static bool evaluateVarDeclInit(EvalInfo , const Expr *E,
>>  const VarDecl *VD, CallStackFrame *Frame,
>>  APValue *) {
>> +
>>// If this is a parameter to an active constexpr function call, perform
>>// argument substitution.
>>if (const ParmVarDecl *PVD = dyn_cast(VD)) {
>> @@ -4180,6 +4196,10 @@ static bool HandleFunctionCall(SourceLoc
>>return false;
>>  This->moveInto(Result);
>>  return true;
>> +  } else if (MD && isLambdaCallOperator(MD)) {
>> +// We're in a lambda; determine the lambda capture field maps.
>> +MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields,
>> +  Frame.LambdaThisCaptureField);
>>}
>>
>>StmtResult Ret = {Result, ResultSlot};
>> @@ -5041,6 +5061,33 @@ bool LValueExprEvaluator::VisitDeclRefEx
>>
>>
>>  bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD)
>> {
>> +
>> +  // If we are within a lambda's call operator, check whether the 'VD'
>> refer

r295279 - [cxx1z-constexpr-lambda] Implement captures - thus completing implementation of constexpr lambdas.

2017-02-15 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Wed Feb 15 22:12:21 2017
New Revision: 295279

URL: http://llvm.org/viewvc/llvm-project?rev=295279=rev
Log:
[cxx1z-constexpr-lambda] Implement captures - thus completing implementation of 
constexpr lambdas.

Enable evaluation of captures within constexpr lambdas by using a strategy 
similar to that used in CodeGen:
  - when starting evaluation of a lambda's call operator, create a map from 
VarDecl's to a closure's FieldDecls
  - every time a VarDecl (or '*this) that represents a capture is encountered 
while evaluating the expression via the expression evaluator (specifically the 
LValueEvaluator) in ExprConstant.cpp - it is replaced by the corresponding 
FieldDecl LValue (an Lvalue-to-Rvalue conversion on this LValue representation 
then determines the right rvalue when needed).

Thanks to Richard Smith and Hubert Tong for their review and feedback!

https://reviews.llvm.org/D29748


Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=295279=295278=295279=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Feb 15 22:12:21 2017
@@ -425,6 +425,17 @@ namespace {
 /// Index - The call index of this call.
 unsigned Index;
 
+// FIXME: Adding this to every 'CallStackFrame' may have a nontrivial 
impact
+// on the overall stack usage of deeply-recursing constexpr evaluataions.
+// (We should cache this map rather than recomputing it repeatedly.)
+// But let's try this and see how it goes; we can look into caching the map
+// as a later change.
+
+/// LambdaCaptureFields - Mapping from captured variables/this to
+/// corresponding data members in the closure class.
+llvm::DenseMap LambdaCaptureFields;
+FieldDecl *LambdaThisCaptureField;
+
 CallStackFrame(EvalInfo , SourceLocation CallLoc,
const FunctionDecl *Callee, const LValue *This,
APValue *Arguments);
@@ -2279,6 +2290,10 @@ static bool HandleLValueComplexElement(E
   return true;
 }
 
+static bool handleLValueToRValueConversion(EvalInfo , const Expr *Conv,
+   QualType Type, const LValue ,
+   APValue );
+
 /// Try to evaluate the initializer for a variable declaration.
 ///
 /// \param Info   Information about the ongoing evaluation.
@@ -2290,6 +2305,7 @@ static bool HandleLValueComplexElement(E
 static bool evaluateVarDeclInit(EvalInfo , const Expr *E,
 const VarDecl *VD, CallStackFrame *Frame,
 APValue *) {
+
   // If this is a parameter to an active constexpr function call, perform
   // argument substitution.
   if (const ParmVarDecl *PVD = dyn_cast(VD)) {
@@ -4180,6 +4196,10 @@ static bool HandleFunctionCall(SourceLoc
   return false;
 This->moveInto(Result);
 return true;
+  } else if (MD && isLambdaCallOperator(MD)) {
+// We're in a lambda; determine the lambda capture field maps.
+MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields,
+  Frame.LambdaThisCaptureField);
   }
 
   StmtResult Ret = {Result, ResultSlot};
@@ -5041,6 +5061,33 @@ bool LValueExprEvaluator::VisitDeclRefEx
 
 
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
+
+  // If we are within a lambda's call operator, check whether the 'VD' referred
+  // to within 'E' actually represents a lambda-capture that maps to a
+  // data-member/field within the closure object, and if so, evaluate to the
+  // field or what the field refers to.
+  if (Info.CurrentCall && isLambdaCallOperator(Info.CurrentCall->Callee)) {
+if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
+  if (Info.checkingPotentialConstantExpression())
+return false;
+  // Start with 'Result' referring to the complete closure object...
+  Result = *Info.CurrentCall->This;
+  // ... then update it to refer to the field of the closure object
+  // that represents the capture.
+  if (!HandleLValueMember(Info, E, Result, FD))
+return false;
+  // And if the field is of reference type, update 'Result' to refer to 
what
+  // the field refers to.
+  if (FD->getType()->isReferenceType()) {
+APValue RVal;
+if (!handleLValueToRValueConversion(Info, E, FD->getType(), Result,
+RVal))
+  return false;
+Result.setFrom(Info.Ctx, RVal);
+  }
+  return true;
+}
+  }
   CallStackFrame *Frame = nullptr;
   if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) {
 // Only if a local variable was declared in the function currently being
@@ 

r291525 - [NFC] Rename RAII ExpressionEvaluationContext variable from Unevaluated to ConstantEvaluated when parsing a constant expression.

2017-01-09 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Jan  9 19:29:41 2017
New Revision: 291525

URL: http://llvm.org/viewvc/llvm-project?rev=291525=rev
Log:
[NFC] Rename RAII ExpressionEvaluationContext variable from Unevaluated to 
ConstantEvaluated when parsing a constant expression.

This renaming makes it consistent with the context it actually sets: 
Sema::ConstantEvaluated.

Modified:
cfe/trunk/lib/Parse/ParseExpr.cpp

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=291525=291524=291525=diff
==
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Mon Jan  9 19:29:41 2017
@@ -198,7 +198,7 @@ ExprResult Parser::ParseConstantExpressi
   //   An expression is potentially evaluated unless it appears where an
   //   integral constant expression is required (see 5.19) [...].
   // C++98 and C++11 have no such rule, but this is only a defect in C++98.
-  EnterExpressionEvaluationContext Unevaluated(Actions,
+  EnterExpressionEvaluationContext ConstantEvaluated(Actions,
Sema::ConstantEvaluated);
 
   ExprResult LHS(ParseCastExpression(false, false, isTypeCast));


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r291439 - [cxx1z-constexpr-lambda] [NFC] Add a FIXME to reinstate certain restrictions on constexpr lambdas from appearing within function-signatures (CWG1607)

2017-01-09 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Jan  9 05:47:51 2017
New Revision: 291439

URL: http://llvm.org/viewvc/llvm-project?rev=291439=rev
Log:
[cxx1z-constexpr-lambda] [NFC] Add a FIXME to reinstate certain restrictions on 
constexpr lambdas from appearing within function-signatures (CWG1607)

For further background, see Richard's comments: 
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20170109/181998.html

A patch to fix this is being worked on.

Thanks!

Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=291439=291438=291439=diff
==
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jan  9 05:47:51 2017
@@ -13118,7 +13118,13 @@ void Sema::PopExpressionEvaluationContex
 //   evaluate [...] a lambda-expression.
 D = diag::err_lambda_in_constant_expression;
   }
+
   // C++1z allows lambda expressions as core constant expressions.
+  // FIXME: In C++1z, reinstate the restrictions on lambda expressions (CWG
+  // 1607) from appearing within template-arguments and array-bounds that
+  // are part of function-signatures.  Be mindful that P0315 (Lambdas in
+  // unevaluated contexts) might lift some of these restrictions in a 
+  // future version.
   if (Rec.Context != ConstantEvaluated || !getLangOpts().CPlusPlus1z)
 for (const auto *L : Rec.Lambdas)
   Diag(L->getLocStart(), D);


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r291416 - [cxx1z-constexpr-lambda] Implement constant evaluation of non-capturing lambda expressions.

2017-01-09 Thread Faisal Vali via cfe-commits
On Mon, Jan 9, 2017 at 12:13 AM, Richard Smith <rich...@metafoo.co.uk> wrote:
> On 8 January 2017 at 19:02, Faisal Vali via cfe-commits
> <cfe-commits@lists.llvm.org> wrote:
>>
>> Author: faisalv
>> Date: Sun Jan  8 21:02:53 2017
>> New Revision: 291416
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=291416=rev
>> Log:
>> [cxx1z-constexpr-lambda] Implement constant evaluation of non-capturing
>> lambda expressions.
>>
>> Add a visitor for lambda expressions to RecordExprEvaluator in
>> ExprConstant.cpp that creates an empty APValue of Struct type to represent
>> the closure object. Additionally, add a LambdaExpr visitor to the
>> TemporaryExprEvaluator that forwards constant evaluation of
>> immediately-called-lambda-expressions to the one in RecordExprEvaluator
>> through VisitConstructExpr.
>>
>> This patch supports:
>> constexpr auto ID = [] (auto a) { return a; };
>> static_assert(ID(3.14) == 3.14);
>> static_assert([](auto a) { return a + 1; }(10) == 11);
>>
>> Lambda captures are still not supported for constexpr lambdas.
>>
>>
>> Modified:
>> cfe/trunk/lib/AST/ExprConstant.cpp
>> cfe/trunk/lib/Sema/SemaExpr.cpp
>> cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
>>
>> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=291416=291415=291416=diff
>>
>> ==
>> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
>> +++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Jan  8 21:02:53 2017
>> @@ -5868,6 +5868,7 @@ namespace {
>>  bool VisitCXXConstructExpr(const CXXConstructExpr *E) {
>>return VisitCXXConstructExpr(E, E->getType());
>>  }
>> +bool VisitLambdaExpr(const LambdaExpr *E);
>>  bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr
>> *E);
>>  bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T);
>>  bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr
>> *E);
>> @@ -6202,6 +6203,21 @@ bool RecordExprEvaluator::VisitCXXStdIni
>>return true;
>>  }
>>
>> +bool RecordExprEvaluator::VisitLambdaExpr(const LambdaExpr *E) {
>> +  const CXXRecordDecl *ClosureClass = E->getLambdaClass();
>> +  if (ClosureClass->isInvalidDecl()) return false;
>> +
>> +  if (Info.checkingPotentialConstantExpression()) return true;
>> +  if (E->capture_size()) {
>> +Info.FFDiag(E, diag::note_unimplemented_constexpr_lambda_feature_ast)
>> +<< "can not evaluate lambda expressions with captures";
>> +return false;
>> +  }
>> +  // FIXME: Implement captures.
>> +  Result = APValue(APValue::UninitStruct(), /*NumBases*/0,
>> /*NumFields*/0);
>> +  return true;
>> +}
>> +
>>  static bool EvaluateRecord(const Expr *E, const LValue ,
>> APValue , EvalInfo ) {
>>assert(E->isRValue() && E->getType()->isRecordType() &&
>> @@ -6251,6 +6267,9 @@ public:
>>bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E)
>> {
>>  return VisitConstructExpr(E);
>>}
>> +  bool VisitLambdaExpr(const LambdaExpr *E) {
>> +return VisitConstructExpr(E);
>> +  }
>>  };
>>  } // end anonymous namespace
>>
>>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=291416=291415=291416=diff
>>
>> ==
>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Jan  8 21:02:53 2017
>> @@ -13097,8 +13097,10 @@ void Sema::PopExpressionEvaluationContex
>>  //   evaluate [...] a lambda-expression.
>>  D = diag::err_lambda_in_constant_expression;
>>}
>> -  for (const auto *L : Rec.Lambdas)
>> -Diag(L->getLocStart(), D);
>> +  // C++1z allows lambda expressions as core constant expressions.
>> +  if (Rec.Context != ConstantEvaluated || !getLangOpts().CPlusPlus1z)
>> +for (const auto *L : Rec.Lambdas)
>> +  Diag(L->getLocStart(), D);
>
>
> We'll need an implementation of DR1607 before we're done here, since it
> looks like this has removed the last restriction on lambda-expressions in
> function template signatures in some contexts (array bounds, template
> arguments).
>

Yes - I'll add those restrictions back (I suppose we'll need to check
whether the nearest enclosing non-lambda context is a valid one [while
still allowing them in default function arguments]) - but then we'll
need to relax some of them when we implement P0315 in post-C++-17
right?

For e.g. these would be ok w P0315 right?

template struct X { };

X<[](auto a){ return a; }(10)> x;


Thanks!
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r291416 - [cxx1z-constexpr-lambda] Implement constant evaluation of non-capturing lambda expressions.

2017-01-08 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Jan  8 21:02:53 2017
New Revision: 291416

URL: http://llvm.org/viewvc/llvm-project?rev=291416=rev
Log:
[cxx1z-constexpr-lambda] Implement constant evaluation of non-capturing lambda 
expressions.

Add a visitor for lambda expressions to RecordExprEvaluator in ExprConstant.cpp 
that creates an empty APValue of Struct type to represent the closure object. 
Additionally, add a LambdaExpr visitor to the TemporaryExprEvaluator that 
forwards constant evaluation of immediately-called-lambda-expressions to the 
one in RecordExprEvaluator through VisitConstructExpr.

This patch supports:
constexpr auto ID = [] (auto a) { return a; };
static_assert(ID(3.14) == 3.14);
static_assert([](auto a) { return a + 1; }(10) == 11);

Lambda captures are still not supported for constexpr lambdas.


Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=291416=291415=291416=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Jan  8 21:02:53 2017
@@ -5868,6 +5868,7 @@ namespace {
 bool VisitCXXConstructExpr(const CXXConstructExpr *E) {
   return VisitCXXConstructExpr(E, E->getType());
 }
+bool VisitLambdaExpr(const LambdaExpr *E);
 bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);
 bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T);
 bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E);
@@ -6202,6 +6203,21 @@ bool RecordExprEvaluator::VisitCXXStdIni
   return true;
 }
 
+bool RecordExprEvaluator::VisitLambdaExpr(const LambdaExpr *E) {
+  const CXXRecordDecl *ClosureClass = E->getLambdaClass();
+  if (ClosureClass->isInvalidDecl()) return false;
+
+  if (Info.checkingPotentialConstantExpression()) return true;
+  if (E->capture_size()) {
+Info.FFDiag(E, diag::note_unimplemented_constexpr_lambda_feature_ast)
+<< "can not evaluate lambda expressions with captures";
+return false;
+  }
+  // FIXME: Implement captures.
+  Result = APValue(APValue::UninitStruct(), /*NumBases*/0, /*NumFields*/0);
+  return true;
+}
+
 static bool EvaluateRecord(const Expr *E, const LValue ,
APValue , EvalInfo ) {
   assert(E->isRValue() && E->getType()->isRecordType() &&
@@ -6251,6 +6267,9 @@ public:
   bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E) {
 return VisitConstructExpr(E);
   }
+  bool VisitLambdaExpr(const LambdaExpr *E) {
+return VisitConstructExpr(E);
+  }
 };
 } // end anonymous namespace
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=291416=291415=291416=diff
==
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Jan  8 21:02:53 2017
@@ -13097,8 +13097,10 @@ void Sema::PopExpressionEvaluationContex
 //   evaluate [...] a lambda-expression.
 D = diag::err_lambda_in_constant_expression;
   }
-  for (const auto *L : Rec.Lambdas)
-Diag(L->getLocStart(), D);
+  // C++1z allows lambda expressions as core constant expressions.
+  if (Rec.Context != ConstantEvaluated || !getLangOpts().CPlusPlus1z)
+for (const auto *L : Rec.Lambdas)
+  Diag(L->getLocStart(), D);
 } else {
   // Mark the capture expressions odr-used. This was deferred
   // during lambda expression creation.

Modified: cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp?rev=291416=291415=291416=diff
==
--- cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp Sun Jan  8 21:02:53 2017
@@ -96,4 +96,81 @@ decltype(deduced_return_type(0)) d;  //e
 
 } // end ns test_conversion_function_for_non_capturing_lambdas
 
+namespace test_lambda_is_cce {
+namespace ns1_simple_lambda {
+
+namespace ns0 {
+constexpr int I = [](auto a) { return a; }(10);
+
+static_assert(I == 10); 
+static_assert(10 == [](auto a) { return a; }(10));
+static_assert(3.14 == [](auto a) { return a; }(3.14));
+
+} //end ns0
+
+namespace ns1 {
+constexpr auto f(int i) {
+  double d = 3.14;
+  auto L = [=](auto a) { 
+int Isz = sizeof(i);
+return sizeof(i) + sizeof(a) + sizeof(d); 
+  };
+  int I = L("abc") + L(nullptr);
+  return L;
+}
+constexpr auto L = f(3);
+constexpr auto M =  L("abc") + L(nullptr);
+
+static_assert(M == sizeof(int) * 2 + sizeof(double) * 2 + sizeof(nullptr) + 
sizeof(const char*));
+
+} // end ns1
+

r291397 - [cxx1z-constexpr-lambda] Make conversion function constexpr, and teach the expression-evaluator to evaluate the static-invoker.

2017-01-08 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Jan  8 12:56:11 2017
New Revision: 291397

URL: http://llvm.org/viewvc/llvm-project?rev=291397=rev
Log:
[cxx1z-constexpr-lambda] Make conversion function constexpr, and teach the 
expression-evaluator to evaluate the static-invoker.

This patch has been sitting in review hell since july 2016 and our lack of 
constexpr lambda support is getting embarrassing (given that I've had a branch 
that implements the feature (modulo *this capture) for over a year.  While in 
Issaquah I was enjoying shamelessly trying to convince folks of the lie that 
this was Richard's fault ;) I won't be able to do so in Kona since I won't be 
attending - so I'm going to aim to have this feature be implemented by then.

I'm quite confident of the approach in this patch, which simply maps the 
static-invoker 'thunk' back to the corresponding call-operator (specialization).

Thanks!


Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaLambda.cpp
cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=291397=291396=291397=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Jan  8 12:56:11 2017
@@ -4543,6 +4543,12 @@ public:
  Call.getLValueBase().dyn_cast());
   if (!FD)
 return Error(Callee);
+  // Don't call function pointers which have been cast to some other type.
+  // Per DR (no number yet), the caller and callee can differ in noexcept.
+  if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
+CalleeType->getPointeeType(), FD->getType())) {
+return Error(E);
+  }
 
   // Overloaded operator calls to member functions are represented as 
normal
   // calls with '*this' as the first argument.
@@ -4558,14 +4564,42 @@ public:
   return false;
 This = 
 Args = Args.slice(1);
-  }
+  } else if (MD && MD->isLambdaStaticInvoker()) {   
+// Map the static invoker for the lambda back to the call operator.
+// Conveniently, we don't have to slice out the 'this' argument (as is
+// being done for the non-static case), since a static member function
+// doesn't have an implicit argument passed in.
+const CXXRecordDecl *ClosureClass = MD->getParent();
+assert(
+ClosureClass->captures_begin() == ClosureClass->captures_end() &&
+"Number of captures must be zero for conversion to function-ptr");
 
-  // Don't call function pointers which have been cast to some other type.
-  // Per DR (no number yet), the caller and callee can differ in noexcept.
-  if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
-  CalleeType->getPointeeType(), FD->getType())) {
-return Error(E);
+const CXXMethodDecl *LambdaCallOp =
+ClosureClass->getLambdaCallOperator();
+
+// Set 'FD', the function that will be called below, to the call
+// operator.  If the closure object represents a generic lambda, find
+// the corresponding specialization of the call operator.
+
+if (ClosureClass->isGenericLambda()) {
+  assert(MD->isFunctionTemplateSpecialization() &&
+ "A generic lambda's static-invoker function must be a "
+ "template specialization");
+  const TemplateArgumentList *TAL = 
MD->getTemplateSpecializationArgs();
+  FunctionTemplateDecl *CallOpTemplate =
+  LambdaCallOp->getDescribedFunctionTemplate();
+  void *InsertPos = nullptr;
+  FunctionDecl *CorrespondingCallOpSpecialization =
+  CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
+  assert(CorrespondingCallOpSpecialization &&
+ "We must always have a function call operator specialization "
+ "that corresponds to our static invoker specialization");
+  FD = cast(CorrespondingCallOpSpecialization);
+} else
+  FD = LambdaCallOp;
   }
+
+  
 } else
   return Error(E);
 

Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=291397=291396=291397=diff
==
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Sun Jan  8 12:56:11 2017
@@ -1274,7 +1274,7 @@ static void addFunctionPointerConversion
 ConvTy, 
 ConvTSI,
 /*isInline=*/true, /*isExplicit=*/false,
-/*isConstexpr=*/false, 
+/*isConstexpr=*/S.getLangOpts().CPlusPlus1z, 

[PATCH] D22997: [cxx1z-constexpr-lambda] Make conversion function constexpr, and teach the expression-evaluator to evaluate the static-invoker.

2016-11-14 Thread Faisal Vali via cfe-commits
faisalv updated this revision to Diff 77926.
faisalv marked an inline comment as done.
faisalv added a comment.

Simplify the check for zero captures in a lambda expression (within the assert) 
by comparing the begin and end pointers directly (as opposed to using distance) 
- thanks to Akira!


https://reviews.llvm.org/D22997

Files:
  lib/AST/ExprConstant.cpp
  lib/Sema/SemaLambda.cpp
  test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -59,4 +59,30 @@
 }
 
 }
+
+namespace test_conversion_function_for_non_capturing_lambdas {
+
+namespace ns1 {
+auto L = [](int i) { return i; };
+constexpr int (*fpi)(int) = L;
+static_assert(fpi(3) == 3);
+auto GL = [](auto a) { return a; };
+
+constexpr char (*fp2)(char) = GL;
+constexpr double (*fp3)(double) = GL;
+constexpr const char* (*fp4)(const char*) = GL;
+static_assert(fp2('3') == '3');
+static_assert(fp3(3.14) == 3.14);
+constexpr const char *Str = "abc";
+static_assert(fp4(Str) == Str);
+
+auto NCL = [](int i) { static int j; return j; }; //expected-note{{declared here}}
+constexpr int (*fp5)(int) = NCL;
+constexpr int I = //expected-error{{must be initialized by a constant expression}}
+  fp5(5); //expected-note{{non-constexpr function}}
+
+} // end ns1
+
+} // end ns test_conversion_function_for_non_capturing_lambdas
+
 #endif // ndef CPP14_AND_EARLIER
Index: lib/Sema/SemaLambda.cpp
===
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -1273,7 +1273,7 @@
 ConvTy, 
 ConvTSI,
 /*isInline=*/true, /*isExplicit=*/false,
-/*isConstexpr=*/false, 
+/*isConstexpr=*/S.getLangOpts().CPlusPlus1z, 
 CallOperator->getBody()->getLocEnd());
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4399,6 +4399,10 @@
  Call.getLValueBase().dyn_cast());
   if (!FD)
 return Error(Callee);
+  
+  // Don't call function pointers which have been cast to some other type.
+  if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
+return Error(E);
 
   // Overloaded operator calls to member functions are represented as normal
   // calls with '*this' as the first argument.
@@ -4414,11 +4418,41 @@
   return false;
 This = 
 Args = Args.slice(1);
+  } else if (MD && MD->isLambdaStaticInvoker()) {   
+// Map the static invoker for the lambda back to the call operator.
+// Conveniently, we don't have to slice out the 'this' argument (as is
+// being done for the non-static case), since a static member function
+// doesn't have an implicit argument passed in.
+const CXXRecordDecl *ClosureClass = MD->getParent();
+assert(
+ClosureClass->captures_begin() == ClosureClass->captures_end() &&
+"Number of captures must be zero for conversion to function-ptr");
+
+const CXXMethodDecl *LambdaCallOp =
+ClosureClass->getLambdaCallOperator();
+
+// Set 'FD', the function that will be called below, to the call
+// operator.  If the closure object represents a generic lambda, find
+// the corresponding specialization of the call operator.
+
+if (ClosureClass->isGenericLambda()) {
+  assert(MD->isFunctionTemplateSpecialization() &&
+ "A generic lambda's static-invoker function must be a "
+ "template specialization");
+  const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
+  FunctionTemplateDecl *CallOpTemplate =
+  LambdaCallOp->getDescribedFunctionTemplate();
+  void *InsertPos = nullptr;
+  FunctionDecl *CorrespondingCallOpSpecialization =
+  CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
+  assert(CorrespondingCallOpSpecialization &&
+ "We must always have a function call operator specialization "
+ "that corresponds to our static invoker specialization");
+  FD = cast(CorrespondingCallOpSpecialization);
+} else
+  FD = LambdaCallOp;
   }
-
-  // Don't call function pointers which have been cast to some other type.
-  if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
-return Error(E);
+  
 } else
   return Error(E);
 
___
cfe-commits 

[PATCH] D22997: [cxx1z-constexpr-lambda] Make conversion function constexpr, and teach the expression-evaluator to evaluate the static-invoker.

2016-11-13 Thread Faisal Vali via cfe-commits
faisalv removed rL LLVM as the repository for this revision.
faisalv updated this revision to Diff 77767.
faisalv marked 4 inline comments as done.
faisalv added a comment.

Addressed Aaron's requests regarding improving formatting and assert messages.

Thanks!


https://reviews.llvm.org/D22997

Files:
  lib/AST/ExprConstant.cpp
  lib/Sema/SemaLambda.cpp
  test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -59,4 +59,30 @@
 }
 
 }
+
+namespace test_conversion_function_for_non_capturing_lambdas {
+
+namespace ns1 {
+auto L = [](int i) { return i; };
+constexpr int (*fpi)(int) = L;
+static_assert(fpi(3) == 3);
+auto GL = [](auto a) { return a; };
+
+constexpr char (*fp2)(char) = GL;
+constexpr double (*fp3)(double) = GL;
+constexpr const char* (*fp4)(const char*) = GL;
+static_assert(fp2('3') == '3');
+static_assert(fp3(3.14) == 3.14);
+constexpr const char *Str = "abc";
+static_assert(fp4(Str) == Str);
+
+auto NCL = [](int i) { static int j; return j; }; //expected-note{{declared here}}
+constexpr int (*fp5)(int) = NCL;
+constexpr int I = //expected-error{{must be initialized by a constant expression}}
+  fp5(5); //expected-note{{non-constexpr function}}
+
+} // end ns1
+
+} // end ns test_conversion_function_for_non_capturing_lambdas
+
 #endif // ndef CPP14_AND_EARLIER
Index: lib/Sema/SemaLambda.cpp
===
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -1273,7 +1273,7 @@
 ConvTy, 
 ConvTSI,
 /*isInline=*/true, /*isExplicit=*/false,
-/*isConstexpr=*/false, 
+/*isConstexpr=*/S.getLangOpts().CPlusPlus1z, 
 CallOperator->getBody()->getLocEnd());
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4399,6 +4399,10 @@
  Call.getLValueBase().dyn_cast());
   if (!FD)
 return Error(Callee);
+  
+  // Don't call function pointers which have been cast to some other type.
+  if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
+return Error(E);
 
   // Overloaded operator calls to member functions are represented as normal
   // calls with '*this' as the first argument.
@@ -4414,11 +4418,41 @@
   return false;
 This = 
 Args = Args.slice(1);
+  } else if (MD && MD->isLambdaStaticInvoker()) {   
+// Map the static invoker for the lambda back to the call operator.
+// Conveniently, we don't have to slice out the 'this' argument (as is
+// being done for the non-static case), since a static member function
+// doesn't have an implicit argument passed in.
+const CXXRecordDecl *ClosureClass = MD->getParent();
+assert((std::distance(ClosureClass->captures_begin(),
+  ClosureClass->captures_end()) == 0) &&
+   "Number of captures shall be zero if we are able to convert to "
+   "pointer to function");
+const CXXMethodDecl *LambdaCallOp =
+ClosureClass->getLambdaCallOperator();
+
+// Set 'FD', the function that will be called below, to the call
+// operator.  If the closure object represents a generic lambda, find
+// the corresponding specialization of the call operator.
+
+if (ClosureClass->isGenericLambda()) {
+  assert(MD->isFunctionTemplateSpecialization() &&
+ "A generic lambda's static-invoker function must be a "
+ "template specialization");
+  const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
+  FunctionTemplateDecl *CallOpTemplate =
+  LambdaCallOp->getDescribedFunctionTemplate();
+  void *InsertPos = nullptr;
+  FunctionDecl *CorrespondingCallOpSpecialization =
+  CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
+  assert(CorrespondingCallOpSpecialization &&
+ "We must always have a function call operator specialization "
+ "that corresponds to our static invoker specialization");
+  FD = cast(CorrespondingCallOpSpecialization);
+} else
+  FD = LambdaCallOp;
   }
-
-  // Don't call function pointers which have been cast to some other type.
-  if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
-return Error(E);
+  
 } else
   return Error(E);
 

[PATCH] D23493: Fix PR28366: Teach the const-expression evaluator to be more fault tolerant with non-const enclosing local variables, or otherwise fold them if const.

2016-11-12 Thread Faisal Vali via cfe-commits
faisalv closed this revision.
faisalv added a comment.

Fixed by commit: r286748
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20161107/176865.html
Thanks for the review!


https://reviews.llvm.org/D23493



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r286748 - Fix PR28366: Handle variables from enclosing local scopes more gracefully during constant expression evaluation.

2016-11-12 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sun Nov 13 00:09:16 2016
New Revision: 286748

URL: http://llvm.org/viewvc/llvm-project?rev=286748=rev
Log:
Fix PR28366: Handle variables from enclosing local scopes more gracefully 
during constant expression evaluation.

Only look for a variable's value in the constant expression evaluation 
activation frame, if the variable was indeed declared in that frame, otherwise 
it might be a constant expression and be usable within a nested local scope or 
emit an error.


void f(char c) { 
  struct X {
static constexpr char f() { 
  return c; // error gracefully here as opposed to crashing.
}
  };
  int I = X::f();
}


Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=286748=286747=286748=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Nov 13 00:09:16 2016
@@ -4803,10 +4803,21 @@ bool LValueExprEvaluator::VisitDeclRefEx
   return Error(E);
 }
 
+
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
   CallStackFrame *Frame = nullptr;
-  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1)
-Frame = Info.CurrentCall;
+  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) {
+// Only if a local variable was declared in the function currently being
+// evaluated, do we expect to be able to find its value in the current
+// frame. (Otherwise it was likely declared in an enclosing context and
+// could either have a valid evaluatable value (for e.g. a constexpr
+// variable) or be ill-formed (and trigger an appropriate evaluation
+// diagnostic)).
+if (Info.CurrentCall->Callee &&
+Info.CurrentCall->Callee->Equals(VD->getDeclContext())) {
+  Frame = Info.CurrentCall;
+}
+  }
 
   if (!VD->getType()->isReferenceType()) {
 if (Frame) {

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=286748=286747=286748=diff
==
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sun Nov 13 00:09:16 2016
@@ -188,7 +188,7 @@ static void instantiateDependentEnableIf
 
   SmallVector Diags;
   if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
-  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(Tmpl),
+  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(New),
 Diags)) {
 S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr);
 for (int I = 0, N = Diags.size(); I != N; ++I)

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=286748=286747=286748=diff
==
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Sun Nov 13 00:09:16 
2016
@@ -2066,3 +2066,33 @@ namespace InheritedCtor {
   constexpr Z z(1);
   static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
 }
+
+
+namespace PR28366 {
+namespace ns1 {
+
+void f(char c) { //expected-note2{{declared here}}
+  struct X {
+static constexpr char f() { //expected-error{{never produces a constant 
expression}}
+  return c; //expected-error{{reference to local}} 
expected-note{{non-const variable}}
+}
+  };
+  int I = X::f();
+}
+
+void g() {
+  const int c = 'c';
+  static const int d = 'd';
+  struct X {
+static constexpr int f() {
+  return c + d;
+}
+  };
+  static_assert(X::f() == 'c' + 'd',"");
+}
+
+
+} // end ns1
+
+} //end ns PR28366
+

Modified: cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp?rev=286748=286747=286748=diff
==
--- cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp Sun Nov 13 00:09:16 2016
@@ -46,5 +46,17 @@ namespace ns3 {
 
 } // end ns test_constexpr_call
 
-#endif // ndef CPP14_AND_EARLIER
+namespace test_captureless_lambda {
+void f() {
+  const char c = 'c';
+  auto L = [] { return c; };
+  constexpr char C = L();
+}
+  
+void f(char c) { //expected-note{{declared here}}
+  auto L = [] { return c; }; //expected-error{{cannot be implicitly 

Re: [PATCH] D23493: Fix PR28366: Teach the const-expression evaluator to be more fault tolerant with non-const enclosing local variables, or otherwise fold them if const.

2016-08-18 Thread Faisal Vali via cfe-commits
faisalv added a comment.

Address Richard's comments.



Comment at: lib/Sema/SemaTemplateInstantiateDecl.cpp:190
@@ -189,3 +189,3 @@
   if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
-  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(Tmpl),
+  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(New),
 Diags)) {

rsmith wrote:
> Do we have existing test coverage for this (tests that fail with the 
> ExprConstant change if we don't fix this at the same time)?
Yes we do.  That's how I realized it needed to be fixed - it's enable_if.cpp in 
SemaCXX that has the following test:
template  T templatedBar(T m) attribute((enable_if(m > 0, ""))) { 
return T(); }



https://reviews.llvm.org/D23493



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D23493: Fix PR28366: Teach the const-expression evaluator to be more fault tolerant with non-const enclosing local variables, or otherwise fold them if const.

2016-08-18 Thread Faisal Vali via cfe-commits
faisalv updated this revision to Diff 68644.
faisalv marked 4 inline comments as done.
faisalv added a comment.

Address Richard's comments.


https://reviews.llvm.org/D23493

Files:
  lib/AST/ExprConstant.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/SemaCXX/constant-expression-cxx11.cpp

Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -2066,3 +2066,33 @@
   constexpr Z z(1);
   static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
 }
+
+
+namespace PR28366 {
+namespace ns1 {
+
+void f(char c) { //expected-note2{{declared here}}
+  struct X {
+static constexpr char f() { //expected-error{{never produces a constant 
expression}}
+  return c; //expected-error{{reference to local}} 
expected-note{{non-const variable}}
+}
+  };
+  int I = X::f();
+}
+
+void g() {
+  const int c = 'c';
+  static const int d = 'd';
+  struct X {
+static constexpr int f() {
+  return c + d;
+}
+  };
+  static_assert(X::f() == c + d,"");
+}
+
+
+} // end ns1
+
+} //end ns PR28366
+
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -187,7 +187,7 @@
 
   SmallVector Diags;
   if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
-  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(Tmpl),
+  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(New),
 Diags)) {
 S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr);
 for (int I = 0, N = Diags.size(); I != N; ++I)
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4788,10 +4788,21 @@
   return Error(E);
 }
 
+
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
   CallStackFrame *Frame = nullptr;
-  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1)
-Frame = Info.CurrentCall;
+  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) {
+// Only if a local variable was declared in the function currently being
+// evaluated, do we expect to be able to find its value in the current
+// frame. (Otherwise it was likely declared in an enclosing context and
+// could either have a valid evaluatable value (for e.g. a constexpr
+// variable) or be ill-formed (and trigger an appropriate evaluation
+// diagnostic)).
+if (Info.CurrentCall->Callee &&
+Info.CurrentCall->Callee->Equals(VD->getDeclContext())) {
+  Frame = Info.CurrentCall;
+}
+  }
 
   if (!VD->getType()->isReferenceType()) {
 if (Frame) {


Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -2066,3 +2066,33 @@
   constexpr Z z(1);
   static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
 }
+
+
+namespace PR28366 {
+namespace ns1 {
+
+void f(char c) { //expected-note2{{declared here}}
+  struct X {
+static constexpr char f() { //expected-error{{never produces a constant expression}}
+  return c; //expected-error{{reference to local}} expected-note{{non-const variable}}
+}
+  };
+  int I = X::f();
+}
+
+void g() {
+  const int c = 'c';
+  static const int d = 'd';
+  struct X {
+static constexpr int f() {
+  return c + d;
+}
+  };
+  static_assert(X::f() == c + d,"");
+}
+
+
+} // end ns1
+
+} //end ns PR28366
+
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -187,7 +187,7 @@
 
   SmallVector Diags;
   if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
-  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(Tmpl),
+  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(New),
 Diags)) {
 S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr);
 for (int I = 0, N = Diags.size(); I != N; ++I)
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4788,10 +4788,21 @@
   return Error(E);
 }
 
+
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
   CallStackFrame *Frame = nullptr;
-  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1)
-Frame = Info.CurrentCall;
+  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) {
+// Only if a local variable was 

Re: [PATCH] D23485: [Branch 3.9] Remove any traces of partial constexpr lambda implementation (per Richard's request)

2016-08-15 Thread Faisal Vali via cfe-commits
faisalv closed this revision.
faisalv added a comment.

Closed by http://llvm.org/viewvc/llvm-project?view=revision=278771


https://reviews.llvm.org/D23485



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D23493: Fix PR28366: Teach the const-expression evaluator to be more fault tolerant with non-const enclosing local variables, or otherwise fold them if const.

2016-08-15 Thread Faisal Vali via cfe-commits
faisalv marked an inline comment as done.
faisalv added a comment.

https://reviews.llvm.org/D23493



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D23493: Fix PR28366: Teach the const-expression evaluator to be more fault tolerant with non-const enclosing local variables, or otherwise fold them if const.

2016-08-15 Thread Faisal Vali via cfe-commits
faisalv removed rL LLVM as the repository for this revision.
faisalv updated this revision to Diff 68091.
faisalv added a comment.

Updated the patch per Richard's direction (which helped clarify my thinking 
about this): Check only the current call frame - if the VarDecl is contained 
within the current callee - only then does it make sense to dig into the 
stack-variables of the frame.  No other scenario really makes sense (even for 
lambdas, we care about the parent decl-contexts (static binding), not variables 
within the call-frame stack (run-time binding).

Thanks Richard.


https://reviews.llvm.org/D23493

Files:
  lib/AST/ExprConstant.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/SemaCXX/constant-expression-cxx11.cpp

Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -2066,3 +2066,33 @@
   constexpr Z z(1);
   static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
 }
+
+
+namespace PR28366 {
+namespace ns1 {
+
+void f(char c) { //expected-note2{{declared here}}
+  struct X {
+static constexpr char f() { //expected-error{{never produces a constant 
expression}}
+  return c; //expected-error{{reference to local}} 
expected-note{{non-const variable}}
+}
+  };
+  int I = X::f();
+}
+
+void g() {
+  const int c = 'c';
+  static const int d = 'd';
+  struct X {
+static constexpr int f() {
+  return c + d;
+}
+  };
+  constexpr int CD = X::f();
+}
+
+
+} // end ns1
+
+} //end ns PR28366
+
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -187,7 +187,7 @@
 
   SmallVector Diags;
   if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
-  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(Tmpl),
+  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(New),
 Diags)) {
 S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr);
 for (int I = 0, N = Diags.size(); I != N; ++I)
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4788,10 +4788,19 @@
   return Error(E);
 }
 
+
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
   CallStackFrame *Frame = nullptr;
-  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1)
-Frame = Info.CurrentCall;
+  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) {
+// Only if the DeclContext of VD is the same as the called function do we
+// set the Frame to the Current CallStackFrame, so that we can find its
+// associated value from the variable-objects associated with that frame.
+if (Info.CurrentCall->Callee && isa(VD->getDeclContext()) &&
+cast(VD->getDeclContext()->getRedeclContext())
+->getFirstDecl() == Info.CurrentCall->Callee->getFirstDecl()) {
+  Frame = Info.CurrentCall;
+}
+  }
 
   if (!VD->getType()->isReferenceType()) {
 if (Frame) {


Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -2066,3 +2066,33 @@
   constexpr Z z(1);
   static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
 }
+
+
+namespace PR28366 {
+namespace ns1 {
+
+void f(char c) { //expected-note2{{declared here}}
+  struct X {
+static constexpr char f() { //expected-error{{never produces a constant expression}}
+  return c; //expected-error{{reference to local}} expected-note{{non-const variable}}
+}
+  };
+  int I = X::f();
+}
+
+void g() {
+  const int c = 'c';
+  static const int d = 'd';
+  struct X {
+static constexpr int f() {
+  return c + d;
+}
+  };
+  constexpr int CD = X::f();
+}
+
+
+} // end ns1
+
+} //end ns PR28366
+
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -187,7 +187,7 @@
 
   SmallVector Diags;
   if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
-  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(Tmpl),
+  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(New),
 Diags)) {
 S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr);
 for (int I = 0, N = Diags.size(); I != N; ++I)
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ 

[PATCH] D23493: Fix PR28366: Teach the const-expression evaluator to be more fault tolerant with non-const enclosing local variables, or otherwise fold them if const.

2016-08-14 Thread Faisal Vali via cfe-commits
faisalv created this revision.
faisalv added reviewers: rsmith, hans.
faisalv added a subscriber: cfe-commits.
faisalv set the repository for this revision to rL LLVM.

Fix the following Bug:
https://llvm.org/bugs/show_bug.cgi?id=28366

This patch teaches the constant expression evaluator to search the frame stack 
for a local variable (instead of assuming a local variable is on the current 
frame).  

This has the following benefits:
  - if the local variable from an enclosing scope was an error during 
parsing/instantiation - it remains an error (instead of a compiler crash) 
during constant expression evaluation
  - a local variable that is a constant expression from an enclosing scope is 
now evaluatable

Additionally, fix SemaTemplateInstantiateDecl so that when it instantiates the 
enable_if attribute it uses the instantiated declaration (instead of the 
template) when evaluating the condition (so that the instantiated param's decl 
context is correctly found).  This was done to fix the following regression:

template  T templatedBar(T m) __attribute__((enable_if(m > 0, ""))) 
{ return T(); }


  
 

Repository:
  rL LLVM

https://reviews.llvm.org/D23493

Files:
  lib/AST/ExprConstant.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/SemaCXX/constant-expression-cxx11.cpp

Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -2066,3 +2066,33 @@
   constexpr Z z(1);
   static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
 }
+
+
+namespace PR28366 {
+namespace ns1 {
+
+void f(char c) { //expected-note2{{declared here}}
+  struct X {
+static constexpr char f() { //expected-error{{never produces a constant 
expression}}
+  return c; //expected-error{{reference to local}} 
expected-note{{non-const variable}}
+}
+  };
+  int I = X::f();
+}
+
+void g() {
+  const int c = 'c';
+  static const int d = 'd';
+  struct X {
+static constexpr int f() {
+  return c + d;
+}
+  };
+  constexpr int CD = X::f();
+}
+
+
+} // end ns1
+
+} //end ns PR28366
+
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -187,7 +187,7 @@
 
   SmallVector Diags;
   if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
-  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(Tmpl),
+  !Expr::isPotentialConstantExprUnevaluated(Cond, cast(New),
 Diags)) {
 S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr);
 for (int I = 0, N = Diags.size(); I != N; ++I)
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4788,10 +4788,24 @@
   return Error(E);
 }
 
+CallStackFrame *getNearestContainingCallFrame(CallStackFrame *CurFrame,
+  const VarDecl *VD) {
+  if (auto *FD =
+dyn_cast(VD->getDeclContext()->getRedeclContext())) {
+FD = FD->getFirstDecl();
+for (CallStackFrame *It = CurFrame; It; It = It->Caller) {
+  if (It->Callee && FD == It->Callee->getFirstDecl())
+return It;
+}
+  }
+  return nullptr;
+}
+
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
   CallStackFrame *Frame = nullptr;
-  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1)
-Frame = Info.CurrentCall;
+  if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1) {
+Frame = getNearestContainingCallFrame(Info.CurrentCall, VD);
+  }
 
   if (!VD->getType()->isReferenceType()) {
 if (Frame) {


Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -2066,3 +2066,33 @@
   constexpr Z z(1);
   static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
 }
+
+
+namespace PR28366 {
+namespace ns1 {
+
+void f(char c) { //expected-note2{{declared here}}
+  struct X {
+static constexpr char f() { //expected-error{{never produces a constant expression}}
+  return c; //expected-error{{reference to local}} expected-note{{non-const variable}}
+}
+  };
+  int I = X::f();
+}
+
+void g() {
+  const int c = 'c';
+  static const int d = 'd';
+  struct X {
+static constexpr int f() {
+  return c + d;
+}
+  };
+  constexpr int CD = X::f();
+}
+
+
+} // end ns1
+
+} //end ns PR28366
+
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -187,7 +187,7 @@
 
   

Re: [PATCH] D23485: [Branch 3.9] Remove any traces of partial constexpr lambda implementation (per Richard's request)

2016-08-13 Thread Faisal Vali via cfe-commits
faisalv added a comment.

Everything compiles - and all tests in clang/test pass.


https://reviews.llvm.org/D23485



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D23485: [Branch 3.9] Remove any traces of partial constexpr lambda implementation (per Richard's request)

2016-08-13 Thread Faisal Vali via cfe-commits
faisalv created this revision.
faisalv added reviewers: hans, rsmith.
faisalv added a subscriber: cfe-commits.

Per Richard's request here:
https://llvm.org/bugs/show_bug.cgi?id=28366#c10

This patch essentially reverses all the changes from the following commit: 
https://reviews.llvm.org/rL264513 for the branch_3.9.

[This is my first time submitting 'pull requests' for a specific branch.  I 
checked-out the respective release branches for llvm and clang, and reverted 
the above commit (resolved a conflict in the process) and created a patch.  My 
box is currently still compiling and running regression tests (will update the 
revision within the next two hours if any revisions need to be made).  Please 
let me know if I should be doing anything different]




https://reviews.llvm.org/D23485

Files:
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ExprConstant.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/TreeTransform.h
  test/Parser/cxx1z-constexpr-lambdas.cpp
  test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -1,36 +0,0 @@
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s 
-
-namespace test_constexpr_checking {
-
-namespace ns1 {
-  struct NonLit { ~NonLit(); };  //expected-note{{not literal}}
-  auto L = [](NonLit NL) constexpr { }; //expected-error{{not a literal type}}
-} // end ns1
-
-namespace ns2 {
-  auto L = [](int I) constexpr { asm("non-constexpr");  }; //expected-error{{not allowed in constexpr function}}
-} // end ns1
-
-} // end ns test_constexpr_checking
-
-namespace test_constexpr_call {
-
-namespace ns1 {
-  auto L = [](int I) { return I; };
-  static_assert(L(3) == 3);
-} // end ns1
-namespace ns2 {
-  auto L = [](auto a) { return a; };
-  static_assert(L(3) == 3);
-  static_assert(L(3.14) == 3.14);
-}
-namespace ns3 {
-  auto L = [](auto a) { asm("non-constexpr"); return a; }; //expected-note{{declared here}}
-  constexpr int I =  //expected-error{{must be initialized by a constant expression}}
-  L(3); //expected-note{{non-constexpr function}}
-} 
-
-} // end ns test_constexpr_call
\ No newline at end of file
Index: test/Parser/cxx1z-constexpr-lambdas.cpp
===
--- test/Parser/cxx1z-constexpr-lambdas.cpp
+++ test/Parser/cxx1z-constexpr-lambdas.cpp
@@ -1,31 +0,0 @@
-// RUN: %clang_cc1 -std=c++1z %s -verify 
-// RUN: %clang_cc1 -std=c++14 %s -verify 
-// RUN: %clang_cc1 -std=c++11 %s -verify 
-
-
-auto XL0 = [] constexpr { }; //expected-error{{requires '()'}} expected-error{{expected body}}
-auto XL1 = [] () mutable 
- mutable //expected-error{{cannot appear multiple times}}
- mutable { }; //expected-error{{cannot appear multiple times}}
-
-#if __cplusplus > 201402L
-auto XL2 = [] () constexpr mutable constexpr { }; //expected-error{{cannot appear multiple times}}
-auto L = []() mutable constexpr { };
-auto L2 = []() constexpr { };
-auto L4 = []() constexpr mutable { }; 
-auto XL16 = [] () constexpr
-  mutable
-  constexpr   //expected-error{{cannot appear multiple times}}
-  mutable //expected-error{{cannot appear multiple times}}
-  mutable //expected-error{{cannot appear multiple times}}
-  constexpr   //expected-error{{cannot appear multiple times}}
-  constexpr   //expected-error{{cannot appear multiple times}}
-  { };
-
-#else
-auto L = []() mutable constexpr {return 0; }; //expected-warning{{is a C++1z extension}}
-auto L2 = []() constexpr { return 0;};//expected-warning{{is a C++1z extension}}
-auto L4 = []() constexpr mutable { return 0; }; //expected-warning{{is a C++1z extension}}
-#endif
-
-
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -10222,9 +10222,7 @@
   CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
   Class, E->getIntroducerRange(), NewCallOpTSI,
   E->getCallOperator()->getLocEnd(),
-  NewCallOpTSI->getTypeLoc().castAs().getParams(),
-  E->getCallOperator()->isConstexpr());
-
+  NewCallOpTSI->getTypeLoc().castAs().getParams());
   LSI->CallOperator = NewCallOperator;
 
   getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
Index: lib/Sema/SemaLambda.cpp

Re: r276900 - [Sema] Teach getCurrentThisType to reconize lambda in in-class initializer

2016-08-11 Thread Faisal Vali via cfe-commits
On Thu, Aug 11, 2016 at 1:07 PM, Richard Smith  wrote:
> Yes, this should be merged. It's not quite right, but it's certainly better
> than what we had before.

I would agree  that the comment is broken - but, unless i'm missing
something subtle, the subsequent logic and call to
adjustCVQualifiersForCXXThisWithinLambda should handle the scenario
you describe.

>
> On Mon, Aug 8, 2016 at 1:34 PM, Hans Wennborg  wrote:
>>
>> Richard: ping?
>>
>> On Wed, Jul 27, 2016 at 4:46 PM, Hans Wennborg  wrote:
>> > Should this be merged to 3.9?
>> >
>> > Thanks,
>> > Hans
>> >
>> > On Wed, Jul 27, 2016 at 11:25 AM, Erik Pilkington via cfe-commits
>> >  wrote:
>> >> Author: epilk
>> >> Date: Wed Jul 27 13:25:10 2016
>> >> New Revision: 276900
>> >>
>> >> URL: http://llvm.org/viewvc/llvm-project?rev=276900=rev
>> >> Log:
>> >> [Sema] Teach getCurrentThisType to reconize lambda in in-class
>> >> initializer
>> >>
>> >> Fixes PR27994, a crash on valid.
>> >>
>> >> Differential revision: https://reviews.llvm.org/D21145
>> >>
>> >> Modified:
>> >> cfe/trunk/lib/Sema/SemaExprCXX.cpp
>> >> cfe/trunk/test/SemaCXX/lambda-expressions.cpp
>> >>
>> >> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
>> >> URL:
>> >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=276900=276899=276900=diff
>> >>
>> >> ==
>> >> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
>> >> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Jul 27 13:25:10 2016
>> >> @@ -961,32 +961,26 @@ static QualType adjustCVQualifiersForCXX
>> >>  QualType Sema::getCurrentThisType() {
>> >>DeclContext *DC = getFunctionLevelDeclContext();
>> >>QualType ThisTy = CXXThisTypeOverride;
>> >> +
>> >>if (CXXMethodDecl *method = dyn_cast(DC)) {
>> >>  if (method && method->isInstance())
>> >>ThisTy = method->getThisType(Context);
>> >>}
>> >> -  if (ThisTy.isNull()) {
>> >> -if (isGenericLambdaCallOperatorSpecialization(CurContext) &&
>> >> -CurContext->getParent()->getParent()->isRecord()) {
>> >> -  // This is a generic lambda call operator that is being
>> >> instantiated
>> >> -  // within a default initializer - so use the enclosing class as
>> >> 'this'.
>> >> -  // There is no enclosing member function to retrieve the 'this'
>> >> pointer
>> >> -  // from.
>> >> -
>> >> -  // FIXME: This looks wrong. If we're in a lambda within a lambda
>> >> within a
>> >> -  // default member initializer, we need to recurse up more
>> >> parents to find
>> >> -  // the right context. Looks like we should be walking up to the
>> >> parent of
>> >> -  // the closure type, checking whether that is itself a lambda,
>> >> and if so,
>> >> -  // recursing, until we reach a class or a function that isn't a
>> >> lambda
>> >> -  // call operator. And we should accumulate the constness of
>> >> *this on the
>> >> -  // way.
>> >> -
>> >> -  QualType ClassTy = Context.getTypeDeclType(
>> >> -  cast(CurContext->getParent()->getParent()));
>> >> -  // There are no cv-qualifiers for 'this' within default
>> >> initializers,
>> >> -  // per [expr.prim.general]p4.
>> >> -  ThisTy = Context.getPointerType(ClassTy);
>> >> -}
>> >> +
>> >> +  if (ThisTy.isNull() && isLambdaCallOperator(CurContext) &&
>> >> +  !ActiveTemplateInstantiations.empty()) {
>> >> +
>> >> +assert(isa(DC) &&
>> >> +   "Trying to get 'this' type from static method?");
>> >> +
>> >> +// This is a lambda call operator that is being instantiated as a
>> >> default
>> >> +// initializer. DC must point to the enclosing class type, so we
>> >> can recover
>> >> +// the 'this' type from it.
>> >> +
>> >> +QualType ClassTy =
>> >> Context.getTypeDeclType(cast(DC));
>> >> +// There are no cv-qualifiers for 'this' within default
>> >> initializers,
>> >> +// per [expr.prim.general]p4.
>
>
> This is wrong in C++17 onwards: if *this is captured by value by a
> non-mutable lambda, it should become const-qualified.
>
>>
>> >> +ThisTy = Context.getPointerType(ClassTy);
>> >>}
>> >>
>> >>// If we are within a lambda's call operator, the cv-qualifiers of
>> >> 'this'
>> >>
>> >> Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp
>> >> URL:
>> >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=276900=276899=276900=diff
>> >>
>> >> ==
>> >> --- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original)
>> >> +++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Wed Jul 27 13:25:10
>> >> 2016
>> >> @@ -1,5 +1,4 @@
>> >> -// RUN: %clang_cc1 -std=c++11 -Wno-unused-value -fsyntax-only -verify
>> >> -fblocks %s
>> >> -// RUN: %clang_cc1 -std=c++1y -Wno-unused-value -fsyntax-only -verify
>> >> 

[PATCH] D22997: [cxx1z-constexpr-lambda] Make conversion function constexpr, and teach the expression-evaluator to evaluate the static-invoker.

2016-07-30 Thread Faisal Vali via cfe-commits
faisalv created this revision.
faisalv added reviewers: rsmith, hubert.reinterpretcast, aaron.ballman, 
erik.pilkington.
faisalv added a subscriber: cfe-commits.
faisalv set the repository for this revision to rL LLVM.
faisalv added a project: clang-c.


This patch enables the following code:

  auto L = [](int i) { return i; };
  constexpr int (*fpi)(int) = L;
  static_assert(fpi(3) == 3);


Repository:
  rL LLVM

https://reviews.llvm.org/D22997

Files:
  lib/AST/ExprConstant.cpp
  lib/Sema/SemaLambda.cpp
  test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -46,5 +46,31 @@
 
 } // end ns test_constexpr_call
 
+
+namespace test_conversion_function_for_non_capturing_lambdas {
+
+namespace ns1 {
+auto L = [](int i) { return i; };
+constexpr int (*fpi)(int) = L;
+static_assert(fpi(3) == 3);
+auto GL = [](auto a) { return a; };
+
+constexpr char (*fp2)(char) = GL;
+constexpr double (*fp3)(double) = GL;
+constexpr const char* (*fp4)(const char*) = GL;
+static_assert(fp2('3') == '3');
+static_assert(fp3(3.14) == 3.14);
+constexpr const char *Str = "abc";
+static_assert(fp4(Str) == Str);
+
+auto NCL = [](int i) { static int j; return j; }; //expected-note{{declared here}}
+constexpr int (*fp5)(int) = NCL;
+constexpr int I = //expected-error{{must be initialized by a constant expression}}
+  fp5(5); //expected-note{{non-constexpr function}}
+
+} // end ns1
+
+} // end ns test_conversion_function_for_non_capturing_lambdas
+
 #endif // ndef CPP14_AND_EARLIER
 
Index: lib/Sema/SemaLambda.cpp
===
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -1263,7 +1263,7 @@
 ConvTy, 
 ConvTSI,
 /*isInline=*/true, /*isExplicit=*/false,
-/*isConstexpr=*/false, 
+/*isConstexpr=*/S.getLangOpts().CPlusPlus1z, 
 CallOperator->getBody()->getLocEnd());
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4386,6 +4386,10 @@
  Call.getLValueBase().dyn_cast());
   if (!FD)
 return Error(Callee);
+  
+  // Don't call function pointers which have been cast to some other type.
+  if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
+return Error(E);
 
   // Overloaded operator calls to member functions are represented as normal
   // calls with '*this' as the first argument.
@@ -4401,11 +4405,36 @@
   return false;
 This = 
 Args = Args.slice(1);
+  } else if (MD && MD->isLambdaStaticInvoker()) {
+   
+// Map the static invoker for the lambda back to the call operator.
+// Conveniently, we don't have to slice out the 'this' argument (as is
+// being done for the non-static case), since a static member function
+// doesn't have an implicit argument passed in.
+const CXXRecordDecl *ClosureClass = MD->getParent();
+ // number of captures better be zero.
+assert(std::distance(ClosureClass->captures_begin(),
+ ClosureClass->captures_end()) == 0);
+const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator();
+
+// Set 'FD', the function that will be called below, to the call
+// operator.  If the closure object represents a generic lambda, find
+// the corresponding specialization of the call operator.
+
+if (ClosureClass->isGenericLambda()) {
+  assert(MD->isFunctionTemplateSpecialization());
+  const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
+  FunctionTemplateDecl *CallOpTemplate =
+  LambdaCallOp->getDescribedFunctionTemplate();
+  void *InsertPos = nullptr;
+  FunctionDecl *CorrespondingCallOpSpecialization =
+  CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
+  assert(CorrespondingCallOpSpecialization);
+  FD = cast(CorrespondingCallOpSpecialization);
+} else
+  FD = LambdaCallOp;
   }
-
-  // Don't call function pointers which have been cast to some other type.
-  if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
-return Error(E);
+  
 } else
   return Error(E);
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r277287 - [NFC] Rearrange an example-file so the c++14 specific example is on top.

2016-07-30 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Jul 30 20:19:17 2016
New Revision: 277287

URL: http://llvm.org/viewvc/llvm-project?rev=277287=rev
Log:
[NFC] Rearrange an example-file so the c++14 specific example is on top.

This makes it easier to add C++1z examples to the bottom, just before the 
#endif.

Modified:
cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Modified: cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp?rev=277287=277286=277287=diff
==
--- cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp Sat Jul 30 20:19:17 2016
@@ -2,6 +2,17 @@
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing %s 
 // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s 
-DCPP14_AND_EARLIER
 
+
+namespace test_lambda_is_literal {
+#ifdef CPP14_AND_EARLIER
+//expected-error@+4{{not a literal type}}
+//expected-note@+2{{not an aggregate and has no constexpr constructors}}
+#endif
+auto L = [] { };
+constexpr int foo(decltype(L) l) { return 0; }
+
+}
+
 #ifndef CPP14_AND_EARLIER
 namespace test_constexpr_checking {
 
@@ -35,14 +46,5 @@ namespace ns3 {
 
 } // end ns test_constexpr_call
 
-#endif
-
-namespace test_lambda_is_literal {
-#ifdef CPP14_AND_EARLIER
-//expected-error@+4{{not a literal type}}
-//expected-note@+2{{not an aggregate and has no constexpr constructors}}
-#endif
-auto L = [] { };
-constexpr int foo(decltype(L) l) { return 0; }
+#endif // ndef CPP14_AND_EARLIER
 
-}
\ No newline at end of file


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22996: [cxx1z-constexpr-lambda] Implement constant evaluation of non-capturing lambda expressions.

2016-07-30 Thread Faisal Vali via cfe-commits
faisalv created this revision.
faisalv added reviewers: rsmith, hubert.reinterpretcast, aaron.ballman, 
erik.pilkington.
faisalv added a subscriber: cfe-commits.
faisalv set the repository for this revision to rL LLVM.
faisalv added a project: clang-c.

Add a visitor for lambda expressions to RecordExprEvaluator in ExprConstant.cpp 
that creates an empty APValue Struct - thus supporting the following code:

constexpr auto ID = [] (auto a) { return a; };
static_assert(ID(3.14) == 3.14);




Repository:
  rL LLVM

https://reviews.llvm.org/D22996

Files:
  lib/AST/ExprConstant.cpp
  test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -2,6 +2,16 @@
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s 
 // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER
 
+namespace test_lambda_is_literal {
+#ifdef CPP14_AND_EARLIER
+//expected-error@+4{{not a literal type}}
+//expected-note@+2{{not an aggregate and has no constexpr constructors}}
+#endif
+auto L = [] { };
+constexpr int foo(decltype(L) l) { return 0; }
+}
+
+
 #ifndef CPP14_AND_EARLIER
 namespace test_constexpr_checking {
 
@@ -35,14 +45,73 @@
 
 } // end ns test_constexpr_call
 
-#endif
 
-namespace test_lambda_is_literal {
-#ifdef CPP14_AND_EARLIER
-//expected-error@+4{{not a literal type}}
-//expected-note@+2{{not an aggregate and has no constexpr constructors}}
-#endif
-auto L = [] { };
-constexpr int foo(decltype(L) l) { return 0; }
+namespace test_lambda_is_cce {
+namespace ns1_simple_lambda {
 
-}
\ No newline at end of file
+namespace ns1 {
+constexpr auto f(int i) {
+  double d = 3.14;
+  auto L = [=](auto a) { 
+int Isz = sizeof(i);
+return sizeof(i) + sizeof(a) + sizeof(d); 
+  };
+  int I = L("abc") + L(nullptr);
+  return L;
+}
+constexpr auto L = f(3);
+constexpr auto M =  L("abc") + L(nullptr);
+
+static_assert(M == sizeof(int) * 2 + sizeof(double) * 2 + sizeof(nullptr) + sizeof(const char*));
+
+} // end ns1
+
+namespace ns2 {
+constexpr auto f(int i) {
+  auto L = [](auto a) { return a + a; };
+  return L;
+}
+constexpr auto L = f(3);
+constexpr int I = L(6);
+static_assert(I == 12);
+} // end ns2
+
+namespace contained_lambdas_call_operator_is_not_constexpr {
+constexpr auto f(int i) {
+  double d = 3.14;
+  auto L = [=](auto a) { //expected-note{{declared here}}
+int Isz = sizeof(i);
+asm("hello");
+return sizeof(i) + sizeof(a) + sizeof(d); 
+  };
+  return L;
+}
+
+constexpr auto L = f(3);
+
+constexpr auto M =  // expected-error{{must be initialized by}} 
+L("abc"); //expected-note{{non-constexpr function}}
+
+} // end ns contained_lambdas_call_operator_is_not_constexpr
+
+
+
+} // end ns1_simple_lambda
+
+namespace ns1_unimplemented {
+namespace ns1_captures {
+constexpr auto f(int i) {
+  double d = 3.14;
+  auto L = [=](auto a) { //expected-note{{coming soon}}
+int Isz = i + d;
+return sizeof(i) + sizeof(a) + sizeof(d); 
+  };
+  return L;
+}
+constexpr auto M = f(3);  //expected-error{{constant expression}} expected-note{{in call to}}
+} // end ns1_captures
+} // end ns1_unimplemented 
+
+} // end ns test_lambda_is_cce
+
+#endif // ndef CPP14_AND_EARLIER
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -5433,6 +5433,7 @@
 bool VisitCXXConstructExpr(const CXXConstructExpr *E) {
   return VisitCXXConstructExpr(E, E->getType());
 }
+bool VisitLambdaExpr(const LambdaExpr *E);
 bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);
 bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T);
 bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E);
@@ -5764,6 +5765,21 @@
   return true;
 }
 
+bool RecordExprEvaluator::VisitLambdaExpr(const LambdaExpr *E) {
+  const CXXRecordDecl *ClosureClass = E->getLambdaClass();
+  if (ClosureClass->isInvalidDecl()) return false;
+
+  if (Info.checkingPotentialConstantExpression()) return true;
+  if (E->capture_size()) {
+Info.FFDiag(E, diag::note_unimplemented_constexpr_lambda_feature_ast)
+<< "can not evaluate lambda expressions with captures";
+return false;
+  }
+  // FIXME: Implement captures.
+  Result = APValue(APValue::UninitStruct(), /*NumBases*/0, /*NumFields*/0);
+  return true;
+}
+
 static bool EvaluateRecord(const Expr *E, const LValue ,
APValue , EvalInfo ) {
   assert(E->isRValue() && E->getType()->isRecordType() &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D22844: Tweak the diagnostic machinery to emit a NamedDecl's type, instead of empty quotes, if it represents an unnamed TypeDecl.

2016-07-26 Thread Faisal Vali via cfe-commits
faisalv updated this revision to Diff 65654.
faisalv added a comment.

Refactored the common code from each insertion operator into a single template 
function called: addNameDeclOrItsTypeToDiagnostic(...).


https://reviews.llvm.org/D22844

Files:
  include/clang/AST/Decl.h
  lib/AST/ASTContext.cpp
  test/SemaCXX/constant-expression-cxx11.cpp

Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -1137,7 +1137,22 @@
 return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot 
be used in a constant expression}}
   }
 }
+namespace  NonLiteralTypes {
 
+auto L = [] { 
+  return []{}; //expected-note{{lambda at}}
+}; 
+
+constexpr int f(decltype(L()) l) { return 0; } //expected-error{{not a literal 
type}}
+
+auto U = [] { 
+  union { volatile int I; } obj;  //expected-note{{anonymous union at}}
+  return obj; 
+};
+constexpr int f(decltype(U()) l) { return 0; } //expected-error{{not a literal 
type}}
+
+}
+
 namespace ExprWithCleanups {
   struct A { A(); ~A(); int get(); };
   constexpr int get(bool FromA) { return FromA ? A().get() : 1; }
Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -3276,7 +3276,12 @@
 
   return QualType(Decl->TypeForDecl, 0);
 }
-
+namespace clang {
+  QualType getTypeDeclTypeFromASTContext(const TypeDecl *T,
+  ASTContext ) {
+return Ctx.getTypeDeclType(T);
+  }
+}
 /// getTypedefType - Return the unique reference to the type for the
 /// specified typedef name decl.
 QualType
Index: include/clang/AST/Decl.h
===
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -3799,18 +3799,38 @@
   static bool classofKind(Kind K) { return K == Empty; }
 };
 
+
+
+// Helper function that checks to see if the NamedDecl Node is am unnamed
+// TypeDecl (such as a lambda, or anonymous union or struct etc.) and if so 
adds
+// its type to the diagnostic instead of the Decl.
+
+template 
+void addNamedDeclOrItsTypeToDiagnostic(const DiagnosticTy ,
+const NamedDecl *ND) {
+  if (ND && isa(ND) && !ND->getIdentifier()) {
+extern QualType getTypeDeclTypeFromASTContext(const TypeDecl *T,
+  ASTContext );
+QualType Ty(
+getTypeDeclTypeFromASTContext(cast(ND), 
ND->getASTContext()));
+DT.AddTaggedVal(reinterpret_cast(Ty.getAsOpaquePtr()),
+DiagnosticsEngine::ak_qualtype);
+  } else {
+DT.AddTaggedVal(reinterpret_cast(ND),
+DiagnosticsEngine::ak_nameddecl);
+  }
+}
+
 /// Insertion operator for diagnostics.  This allows sending NamedDecl's
 /// into a diagnostic with <<.
 inline const DiagnosticBuilder <<(const DiagnosticBuilder ,
const NamedDecl* ND) {
-  DB.AddTaggedVal(reinterpret_cast(ND),
-  DiagnosticsEngine::ak_nameddecl);
+  addNamedDeclOrItsTypeToDiagnostic(DB, ND); 
   return DB;
 }
 inline const PartialDiagnostic <<(const PartialDiagnostic ,
const NamedDecl* ND) {
-  PD.AddTaggedVal(reinterpret_cast(ND),
-  DiagnosticsEngine::ak_nameddecl);
+  addNamedDeclOrItsTypeToDiagnostic(PD, ND); 
   return PD;
 }
 


Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -1137,7 +1137,22 @@
 return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
   }
 }
+namespace  NonLiteralTypes {
 
+auto L = [] { 
+  return []{}; //expected-note{{lambda at}}
+}; 
+
+constexpr int f(decltype(L()) l) { return 0; } //expected-error{{not a literal type}}
+
+auto U = [] { 
+  union { volatile int I; } obj;  //expected-note{{anonymous union at}}
+  return obj; 
+};
+constexpr int f(decltype(U()) l) { return 0; } //expected-error{{not a literal type}}
+
+}
+
 namespace ExprWithCleanups {
   struct A { A(); ~A(); int get(); };
   constexpr int get(bool FromA) { return FromA ? A().get() : 1; }
Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -3276,7 +3276,12 @@
 
   return QualType(Decl->TypeForDecl, 0);
 }
-
+namespace clang {
+  QualType getTypeDeclTypeFromASTContext(const TypeDecl *T,
+  ASTContext ) {
+return Ctx.getTypeDeclType(T);
+  }
+}
 /// getTypedefType - Return the unique reference to the type for the
 /// specified typedef name decl.
 QualType
Index: include/clang/AST/Decl.h

[PATCH] D22844: Tweak the diagnostic machinery to emit a NamedDecl's type, instead of empty quotes, if it represents an unnamed TypeDecl.

2016-07-26 Thread Faisal Vali via cfe-commits
faisalv created this revision.
faisalv added a reviewer: rsmith.
faisalv added a subscriber: cfe-commits.

Currently the following code triggers diagnostics that match:

auto L = []{ }; //expected-note{{'' is not literal}}
constexpr int f(decltype(L)) { return 0; } //expected-error{{not a literal 
type}}

After applying this patch the diagnostics match:
auto L = []{ }; //expected-note{{'(lambda at )' is not literal}}


As encouraged by Richard during his review of: https://reviews.llvm.org/D22662 .





https://reviews.llvm.org/D22844

Files:
  include/clang/AST/Decl.h
  lib/AST/ASTContext.cpp
  test/SemaCXX/constant-expression-cxx11.cpp

Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -1137,7 +1137,22 @@
 return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot 
be used in a constant expression}}
   }
 }
+namespace  NonLiteralTypes {
 
+auto L = [] { 
+  return []{}; //expected-note{{lambda at}}
+}; 
+
+constexpr int f(decltype(L()) l) { return 0; } //expected-error{{not a literal 
type}}
+
+auto U = [] { 
+  union { volatile int I; } obj;  //expected-note{{anonymous union at}}
+  return obj; 
+};
+constexpr int f(decltype(U()) l) { return 0; } //expected-error{{not a literal 
type}}
+
+}
+
 namespace ExprWithCleanups {
   struct A { A(); ~A(); int get(); };
   constexpr int get(bool FromA) { return FromA ? A().get() : 1; }
Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -3276,7 +3276,12 @@
 
   return QualType(Decl->TypeForDecl, 0);
 }
-
+namespace clang {
+  QualType getTypeDeclTypeFromASTContext(const TypeDecl *T,
+  ASTContext ) {
+return Ctx.getTypeDeclType(T);
+  }
+}
 /// getTypedefType - Return the unique reference to the type for the
 /// specified typedef name decl.
 QualType
Index: include/clang/AST/Decl.h
===
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -3799,18 +3799,39 @@
   static bool classofKind(Kind K) { return K == Empty; }
 };
 
+
+
+
 /// Insertion operator for diagnostics.  This allows sending NamedDecl's
 /// into a diagnostic with <<.
 inline const DiagnosticBuilder <<(const DiagnosticBuilder ,
const NamedDecl* ND) {
-  DB.AddTaggedVal(reinterpret_cast(ND),
+  if (ND && isa(ND) && !ND->getIdentifier()) {
+extern QualType getTypeDeclTypeFromASTContext(const TypeDecl *T,
+  ASTContext );
+QualType Ty(
+getTypeDeclTypeFromASTContext(cast(ND), 
ND->getASTContext()));
+DB.AddTaggedVal(reinterpret_cast(Ty.getAsOpaquePtr()),
+DiagnosticsEngine::ak_qualtype);
+  } else {
+DB.AddTaggedVal(reinterpret_cast(ND),
   DiagnosticsEngine::ak_nameddecl);
+  }
   return DB;
 }
 inline const PartialDiagnostic <<(const PartialDiagnostic ,
const NamedDecl* ND) {
-  PD.AddTaggedVal(reinterpret_cast(ND),
+  if (ND && isa(ND) && !ND->getIdentifier()) {
+extern QualType getTypeDeclTypeFromASTContext(const TypeDecl *T,
+  ASTContext );
+QualType Ty(
+getTypeDeclTypeFromASTContext(cast(ND), 
ND->getASTContext()));
+PD.AddTaggedVal(reinterpret_cast(Ty.getAsOpaquePtr()),
+DiagnosticsEngine::ak_qualtype);
+  } else {
+PD.AddTaggedVal(reinterpret_cast(ND),
   DiagnosticsEngine::ak_nameddecl);
+  }
   return PD;
 }
 


Index: test/SemaCXX/constant-expression-cxx11.cpp
===
--- test/SemaCXX/constant-expression-cxx11.cpp
+++ test/SemaCXX/constant-expression-cxx11.cpp
@@ -1137,7 +1137,22 @@
 return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
   }
 }
+namespace  NonLiteralTypes {
 
+auto L = [] { 
+  return []{}; //expected-note{{lambda at}}
+}; 
+
+constexpr int f(decltype(L()) l) { return 0; } //expected-error{{not a literal type}}
+
+auto U = [] { 
+  union { volatile int I; } obj;  //expected-note{{anonymous union at}}
+  return obj; 
+};
+constexpr int f(decltype(U()) l) { return 0; } //expected-error{{not a literal type}}
+
+}
+
 namespace ExprWithCleanups {
   struct A { A(); ~A(); int get(); };
   constexpr int get(bool FromA) { return FromA ? A().get() : 1; }
Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -3276,7 +3276,12 @@
 
   return QualType(Decl->TypeForDecl, 0);
 }
-
+namespace clang {
+  QualType getTypeDeclTypeFromASTContext(const TypeDecl *T,
+

Re: [PATCH] D22662: [cxx1z-constexpr-lambda] Make a lambda's closure type a literal type in C++1z.

2016-07-22 Thread Faisal Vali via cfe-commits
faisalv accepted this revision.
faisalv added a reviewer: faisalv.
faisalv added a comment.
This revision is now accepted and ready to land.

Thanks Richard.  Your request to separate out and centralize the diagnostic 
portion of the patch certainly seems like a good idea - and I shall do so 
separately.

The approved portion of this small patch is committed as: r276514.

http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160718/165670.html

Thanks!


https://reviews.llvm.org/D22662



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r276514 - [cxx1z-constexpr-lambda] Make a lambda's closure type eligible as a literal-type in C++1z

2016-07-22 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Fri Jul 22 23:05:19 2016
New Revision: 276514

URL: http://llvm.org/viewvc/llvm-project?rev=276514=rev
Log:
[cxx1z-constexpr-lambda] Make a lambda's closure type eligible as a 
literal-type in C++1z


Additionally, for pre-C++1z, instead of forbidding a lambda's closure type from 
being a literal type through circumlocutorily setting 
HasNonLiteralTypeFieldsOrBases falsely to true -- handle lambda's more directly 
in CXXRecordDecl::isLiteral().

One additional small step towards implementing constexpr-lambdas.

Thanks to Richard Smith for his review! 
https://reviews.llvm.org/D22662


Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=276514=276513=276514=diff
==
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Jul 22 23:05:19 2016
@@ -535,11 +535,10 @@ class CXXRecordDecl : public RecordDecl
 MethodTyInfo(Info) {
   IsLambda = true;
 
-  // C++11 [expr.prim.lambda]p3:
-  //   This class type is neither an aggregate nor a literal type.
+  // C++1z [expr.prim.lambda]p4:
+  //   This class type is not an aggregate type.
   Aggregate = false;
   PlainOldData = false;
-  HasNonLiteralTypeFieldsOrBases = true;
 }
 
 /// \brief Whether this lambda is known to be dependent, even if its
@@ -1338,11 +1337,15 @@ public:
   ///
   /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
   /// treating types with trivial default constructors as literal types.
+  ///
+  /// Only in C++1z and beyond, are lambdas literal types.
   bool isLiteral() const {
 return hasTrivialDestructor() &&
-   (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
-hasTrivialDefaultConstructor()) &&
-   !hasNonLiteralTypeFieldsOrBases();
+   (!isLambda() || getASTContext().getLangOpts().CPlusPlus1z) &&
+   !hasNonLiteralTypeFieldsOrBases() &&
+   (isAggregate() || isLambda() ||
+hasConstexprNonCopyMoveConstructor() ||
+hasTrivialDefaultConstructor());
   }
 
   /// \brief If this record is an instantiation of a member class,

Modified: cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp?rev=276514=276513=276514=diff
==
--- cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp Fri Jul 22 23:05:19 2016
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing %s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions 
%s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing -fms-extensions %s 
+// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s 
-DCPP14_AND_EARLIER
 
+#ifndef CPP14_AND_EARLIER
 namespace test_constexpr_checking {
 
 namespace ns1 {
@@ -33,4 +33,16 @@ namespace ns3 {
   L(3); //expected-note{{non-constexpr function}}
 } 
 
-} // end ns test_constexpr_call
\ No newline at end of file
+} // end ns test_constexpr_call
+
+#endif
+
+namespace test_lambda_is_literal {
+#ifdef CPP14_AND_EARLIER
+//expected-error@+4{{not a literal type}}
+//expected-note@+2{{not an aggregate and has no constexpr constructors}}
+#endif
+auto L = [] { };
+constexpr int foo(decltype(L) l) { return 0; }
+
+}
\ No newline at end of file


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D22662: [cxx1z-constexpr-lambda] Make a lambda's closure type a literal type in C++1z.

2016-07-21 Thread Faisal Vali via cfe-commits
faisalv updated this revision to Diff 65026.
faisalv added a comment.

Factor out the diagnostic builder RAII creation (through Sema.Diag) and reduce 
repetition.


https://reviews.llvm.org/D22662

Files:
  include/clang/AST/DeclCXX.h
  lib/Sema/SemaType.cpp
  test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing %s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions 
%s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing -fms-extensions %s 
+// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s 
-DCPP14_AND_EARLIER
 
+#ifndef CPP14_AND_EARLIER
 namespace test_constexpr_checking {
 
 namespace ns1 {
@@ -33,4 +33,16 @@
   L(3); //expected-note{{non-constexpr function}}
 } 
 
-} // end ns test_constexpr_call
\ No newline at end of file
+} // end ns test_constexpr_call
+
+#endif
+
+namespace test_lambda_is_literal {
+#ifdef CPP14_AND_EARLIER
+//expected-error@+4{{not a literal type}}
+//expected-note@+2{{not an aggregate and has no constexpr constructors}}
+#endif
+auto L = [] { };
+constexpr int foo(decltype(L) l) { return 0; }
+
+}
\ No newline at end of file
Index: lib/Sema/SemaType.cpp
===
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -7165,7 +7165,15 @@
   << I.getSourceRange();
   } else if (!RD->isAggregate() && !RD->hasConstexprNonCopyMoveConstructor() &&
  !RD->hasTrivialDefaultConstructor()) {
-Diag(RD->getLocation(), diag::note_non_literal_no_constexpr_ctors) << RD;
+// If the class does not have a name (for e.g. a lambda's closure class) 
use
+// its type which we should know how to pretty-print, otherwise use the
+// class's name.
+auto & =
+Diag(RD->getLocation(), diag::note_non_literal_no_constexpr_ctors);
+if (!RD->getIdentifier())
+  DiagBuilder << Context.getRecordType(RD);
+else
+  DiagBuilder << RD;
   } else if (RD->hasNonLiteralTypeFieldsOrBases()) {
 for (const auto  : RD->bases()) {
   if (!I.getType()->isLiteralType(Context)) {
Index: include/clang/AST/DeclCXX.h
===
--- include/clang/AST/DeclCXX.h
+++ include/clang/AST/DeclCXX.h
@@ -536,11 +536,10 @@
 MethodTyInfo(Info) {
   IsLambda = true;
 
-  // C++11 [expr.prim.lambda]p3:
-  //   This class type is neither an aggregate nor a literal type.
+  // C++1z [expr.prim.lambda]p4:
+  //   This class type is not an aggregate type.
   Aggregate = false;
   PlainOldData = false;
-  HasNonLiteralTypeFieldsOrBases = true;
 }
 
 /// \brief Whether this lambda is known to be dependent, even if its
@@ -1339,11 +1338,15 @@
   ///
   /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
   /// treating types with trivial default constructors as literal types.
+  ///
+  /// Only in C++1z and beyond, are lambdas literal types.
   bool isLiteral() const {
 return hasTrivialDestructor() &&
-   (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
-hasTrivialDefaultConstructor()) &&
-   !hasNonLiteralTypeFieldsOrBases();
+   (!isLambda() || getASTContext().getLangOpts().CPlusPlus1z) &&
+   !hasNonLiteralTypeFieldsOrBases() &&
+   (isAggregate() || isLambda() ||
+hasConstexprNonCopyMoveConstructor() ||
+hasTrivialDefaultConstructor());
   }
 
   /// \brief If this record is an instantiation of a member class,


Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s 
+// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER
 
+#ifndef CPP14_AND_EARLIER
 namespace test_constexpr_checking {
 
 namespace ns1 {
@@ -33,4 +33,16 @@
   L(3); //expected-note{{non-constexpr function}}
 } 
 
-} // end ns test_constexpr_call
\ No newline at end of file
+} // end ns test_constexpr_call
+
+#endif
+
+namespace test_lambda_is_literal {
+#ifdef CPP14_AND_EARLIER
+//expected-error@+4{{not a literal type}}
+//expected-note@+2{{not an aggregate 

Re: [PATCH] D18510: [cxx1z-constexpr-lambda] Make conversion function constexpr

2016-07-05 Thread Faisal Vali via cfe-commits
faisalv updated the summary for this revision.
faisalv updated this revision to Diff 62814.
faisalv added a comment.

Mark the lambda's conversion to function-pointer as incontrovertibly constexpr.

auto L = [](auto a) { return a; };
constexpr int* (*fp)(int*) = L; // This is now allowed.

Instead of inserting the extension/compatibility-warning into the same list 
that houses the notes that identify errors that occurred during 
constant-folding (and subsequently modifying the logic to ignore such warnings 
when determining the result of constant folding), I resorted to the simple 
approach used to emit a warning for integer-overflow (during constant folding) 
by invoking getDiagnostics().Report.

Richard I hope you're OK with this approach - I know in Oulu I was leaning 
towards inserting the warning into the same list that houses the error-notes 
(or potentially creating another one, or having EvalInfo track whether an 
error-note truly occurred instead of relying simply on the size of the list) - 
and while doable (and potentially cleaner) - that change is a larger one that 
requires handing some subtleties, and can be done at a later time, if you feel 
strongly about it.


http://reviews.llvm.org/D18510

Files:
  include/clang/Basic/DiagnosticASTKinds.td
  lib/AST/ExprConstant.cpp
  lib/Sema/SemaLambda.cpp
  test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -2,7 +2,9 @@
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing %s 
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions 
%s 
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing -fms-extensions %s 
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -Wc++14-compat %s 
-DCHECK_COMPATIBILITY_WARNING
 
+#ifndef CHECK_COMPATIBILITY_WARNING
 namespace test_constexpr_checking {
 
 namespace ns1 {
@@ -33,4 +35,17 @@
   L(3); //expected-note{{non-constexpr function}}
 } 
 
-} // end ns test_constexpr_call
\ No newline at end of file
+} // end ns test_constexpr_call
+#endif
+
+#ifdef CHECK_COMPATIBILITY_WARNING
+//expected-warning@+6{{incompatible with C++ standards before C++1z}}
+//expected-warning@+6{{incompatible with C++ standards before C++1z}}
+#endif
+
+namespace ns4 {
+auto L = [](auto a) { return a; };
+constexpr int (*fp1)(int) = L;  
+constexpr int* (*fp2)(int*) = L; 
+
+} // end ns4
\ No newline at end of file
Index: lib/Sema/SemaLambda.cpp
===
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -1261,7 +1261,7 @@
 ConvTy, 
 ConvTSI,
 /*isInline=*/true, /*isExplicit=*/false,
-/*isConstexpr=*/false, 
+/*isConstexpr=*/true, 
 CallOperator->getBody()->getLocEnd());
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4353,6 +4353,17 @@
 if (!EvaluateObjectArgument(Info, ME->getBase(), ThisVal))
   return false;
 Member = ME->getMemberDecl();
+// If this is a non-capturing lambda's closure type's conversion
+// operator that results in a pointer-to-function, remind users that 
the
+// conversion operator itself was made 'constexpr' in C++1z.
+if (const CXXConversionDecl *Conv = 
dyn_cast(Member))
+  if (Conv->getParent()->isLambda()) {
+Info.Ctx.getDiagnostics().Report(
+E->getExprLoc(),
+!Info.Ctx.getLangOpts().CPlusPlus1z
+? diag::ext_constexpr_conversion_on_lambda_cxx1z
+: diag::warn_cxx14_compat_constexpr_conversion_on_lambda);
+  }
 This = 
 HasQualifier = ME->hasQualifier();
   } else if (const BinaryOperator *BE = dyn_cast(Callee)) {
Index: include/clang/Basic/DiagnosticASTKinds.td
===
--- include/clang/Basic/DiagnosticASTKinds.td
+++ include/clang/Basic/DiagnosticASTKinds.td
@@ -162,8 +162,17 @@
 // implementation is complete, and like the preceding constexpr notes belongs
 // in Sema.
 def note_unimplemented_constexpr_lambda_feature_ast : Note<
-"unimplemented constexpr lambda feature: %0 (coming soon!)">;
+  "unimplemented constexpr lambda feature: %0 (coming soon!)">;
 
+// C++1z constexpr lambda expressions
+def warn_cxx14_compat_constexpr_conversion_on_lambda : Warning<
+  "constexpr conversion to pointer-to-function on lambdas is "
+  "incompatible 

r274454 - [Refactor NFC] Rename the (non-CCE, fold-failure) Diag during constant expression evaluation as FFDiag.

2016-07-02 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Sat Jul  2 17:34:24 2016
New Revision: 274454

URL: http://llvm.org/viewvc/llvm-project?rev=274454=rev
Log:
[Refactor NFC] Rename the (non-CCE, fold-failure) Diag during constant 
expression evaluation as FFDiag.

Currently, we have CCEDiags (C++11 core constant expression diags) and Fold 
failure diagnostics [I don't claim to yet fully understand exactly why we need 
the difference].  This patch explicitly replaces Info.Diag (whose use always 
represents a fold failure diag within the file) with Info.FFDiag.  This makes 
it more easily greppable in the file, and just like the name Info.CCEDiag, it 
gives the reader slight further insight into the nature of the diagnostic (as 
opposed to Info.Diag).

This patch is a preliminary refactoring step in an effort to allow support for 
compatibility-warnings and extensions (such as constexpr lambda) during 
constant expression evaluation.

All regressions pass.


Modified:
cfe/trunk/lib/AST/ExprConstant.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=274454=274453=274454=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sat Jul  2 17:34:24 2016
@@ -562,12 +562,12 @@ namespace {
 return false;
   if (NextCallIndex == 0) {
 // NextCallIndex has wrapped around.
-Diag(Loc, diag::note_constexpr_call_limit_exceeded);
+FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
 return false;
   }
   if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
 return true;
-  Diag(Loc, diag::note_constexpr_depth_limit_exceeded)
+  FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
 << getLangOpts().ConstexprCallDepth;
   return false;
 }
@@ -584,7 +584,7 @@ namespace {
 
 bool nextStep(const Stmt *S) {
   if (!StepsLeft) {
-Diag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded);
+FFDiag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded);
 return false;
   }
   --StepsLeft;
@@ -602,11 +602,10 @@ namespace {
 /// Add notes containing a call stack to the current point of evaluation.
 void addCallStack(unsigned Limit);
 
-  public:
-/// Diagnose that the evaluation cannot be folded.
-OptionalDiagnostic Diag(SourceLocation Loc, diag::kind DiagId
-  = diag::note_invalid_subexpr_in_const_expr,
-unsigned ExtraNotes = 0, bool IsCCEDiag = false) {
+  private:
+OptionalDiagnostic Diag(SourceLocation Loc, diag::kind DiagId,
+unsigned ExtraNotes, bool IsCCEDiag) {
+
   if (EvalStatus.Diag) {
 // If we have a prior diagnostic, it will be noting that the expression
 // isn't a constant expression. This diagnostic is more important,
@@ -651,12 +650,20 @@ namespace {
   HasActiveDiagnostic = false;
   return OptionalDiagnostic();
 }
-
-OptionalDiagnostic Diag(const Expr *E, diag::kind DiagId
+  public:
+// Diagnose that the evaluation could not be folded (FF => FoldFailure)
+OptionalDiagnostic
+FFDiag(SourceLocation Loc,
+  diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
+  unsigned ExtraNotes = 0) {
+  return Diag(Loc, DiagId, ExtraNotes, false);
+}
+
+OptionalDiagnostic FFDiag(const Expr *E, diag::kind DiagId
   = diag::note_invalid_subexpr_in_const_expr,
-unsigned ExtraNotes = 0, bool IsCCEDiag = false) {
+unsigned ExtraNotes = 0) {
   if (EvalStatus.Diag)
-return Diag(E->getExprLoc(), DiagId, ExtraNotes, IsCCEDiag);
+return Diag(E->getExprLoc(), DiagId, ExtraNotes, /*IsCCEDiag*/false);
   HasActiveDiagnostic = false;
   return OptionalDiagnostic();
 }
@@ -666,8 +673,7 @@ namespace {
 ///
 /// FIXME: Stop evaluating if we're in EM_ConstantExpression or
 /// EM_PotentialConstantExpression mode and we produce one of these.
-template
-OptionalDiagnostic CCEDiag(LocArg Loc, diag::kind DiagId
+OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId
  = diag::note_invalid_subexpr_in_const_expr,
unsigned ExtraNotes = 0) {
   // Don't override a previous diagnostic. Don't bother collecting
@@ -678,7 +684,11 @@ namespace {
   }
   return Diag(Loc, DiagId, ExtraNotes, true);
 }
-
+OptionalDiagnostic CCEDiag(const Expr *E, diag::kind DiagId
+ = diag::note_invalid_subexpr_in_const_expr,
+   unsigned ExtraNotes = 0) {
+  return CCEDiag(E->getExprLoc(), DiagId, ExtraNotes);
+}
 /// Add a note to a prior diagnostic.
 

Re: [PATCH] D20349: Fix a clang bug in lambda capture of 'this'

2016-06-26 Thread Faisal Vali via cfe-commits
faisalv resigned from this revision.
faisalv removed a reviewer: faisalv.
faisalv added a comment.

Should be fixed by: http://reviews.llvm.org/D19783.

Thanks again for your feedback and all the time you put into this =)


http://reviews.llvm.org/D20349



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D21030: [Sema] Fix rejects-valid where parameter pack was not expanded in type alias

2016-06-14 Thread Faisal Vali via cfe-commits
faisalv added a comment.

Thanks for working on this bug too!



Comment at: lib/Sema/TreeTransform.h:4784
@@ +4783,3 @@
+NewType = getDerived().RebuildPackExpansionType(
+NewType, SourceRange(), Loc, NumExpansions);
+if (NewType.isNull())

Any thoughts on the value of threading EllipsisLoc and PatternRange into this 
function (they are used primarily for a diagnostic that is triggered in Sema if 
NewType does not contain an unexpandedparameter pack - which would never get 
triggered here, so it would be ok to pass in invalid sourelocations and 
sourceranges with an appropriate comment here) - but the fact that 
RebuildPackExpandionType is a customization point, it might not be a bad idea 
to preserve them)?
Alternatively, we could forego calling RebuildPackExpansionType - since OldType 
is decomposed directly into a PackExpansionType -- NewType could be recomposed 
directly via Context.getPackExpansionType(NewType, NumExpansions=0)?

Which brings me to - when we create the new pack expansion type, shouldn't the 
NumExpansions be reset to 0?  The fact that we will have a 
SubstTemplateParameterType replacing the TemplateParameterType within the 
pattern might influence the answer to that...

Also - we should be able to assert here that *NumExpansions should be one?  Can 
you think of a case that it wouldn't be?



http://reviews.llvm.org/D21030



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r272631 - Fix PR28100 - Allow redeclarations of deleted explicit specializations.

2016-06-13 Thread Faisal Vali via cfe-commits
Author: faisalv
Date: Mon Jun 13 22:23:15 2016
New Revision: 272631

URL: http://llvm.org/viewvc/llvm-project?rev=272631=rev
Log:
Fix PR28100 - Allow redeclarations of deleted explicit specializations.

See https://llvm.org/bugs/show_bug.cgi?id=28100.

In r266561 when I implemented allowing explicit specializations of function 
templates to override deleted status, I mistakenly assumed (and hence 
introduced a violable assertion) that when an explicit specialization was being 
declared, the corresponding specialization of the most specialized function 
template that it would get linked to would always be the one that was 
implicitly generated - and so if it was marked as 'deleted' it must have 
inherited it from the primary template and so should be safe to reset its 
deleted status, and set it to being an explicit specialization.  Obviously 
during redeclaration of a deleted explicit specialization, in order to avoid a 
recursive reset, we need to check that the previous specialization is not an 
explicit specialization (instead of assuming and asserting it) and that it 
hasn't been referenced, and so only then is it safe to reset its 'deleted' 
status.

All regression tests pass.

Thanks to Zhendong Su for reporting the bug and David Majnemer for tracking it 
to my commit r266561, and promptly bringing it to my attention.




Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaCXX/delete-and-function-templates.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=272631=272630=272631=diff
==
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Jun 13 22:23:15 2016
@@ -6989,12 +6989,20 @@ bool Sema::CheckFunctionTemplateSpeciali
   // Mark the prior declaration as an explicit specialization, so that later
   // clients know that this is an explicit specialization.
   if (!isFriend) {
-// Explicit specializations do not inherit '=delete' from their primary
-// function template.
-if (Specialization->isDeleted()) {
-  assert(!SpecInfo->isExplicitSpecialization());
-  assert(Specialization->getCanonicalDecl() == Specialization);
-  Specialization->setDeletedAsWritten(false);
+// Since explicit specializations do not inherit '=delete' from their
+// primary function template - check if the 'specialization' that was
+// implicitly generated (during template argument deduction for partial
+// ordering) from the most specialized of all the function templates that
+// 'FD' could have been specializing, has a 'deleted' definition.  If so,
+// first check that it was implicitly generated during template argument
+// deduction by making sure it wasn't referenced, and then reset the 
deleted
+// flag to not-deleted, so that we can inherit that information from 'FD'.
+if (Specialization->isDeleted() && !SpecInfo->isExplicitSpecialization() &&
+!Specialization->getCanonicalDecl()->isReferenced()) {
+  assert(
+  Specialization->getCanonicalDecl() == Specialization &&
+  "This must be the only existing declaration of this specialization");
+  Specialization->setDeletedAsWritten(false);
 }
 SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
 MarkUnusedFileScopedDecl(Specialization);

Modified: cfe/trunk/test/SemaCXX/delete-and-function-templates.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/delete-and-function-templates.cpp?rev=272631=272630=272631=diff
==
--- cfe/trunk/test/SemaCXX/delete-and-function-templates.cpp (original)
+++ cfe/trunk/test/SemaCXX/delete-and-function-templates.cpp Mon Jun 13 
22:23:15 2016
@@ -112,4 +112,22 @@ void foo() {
 
 
 } // end ns3
+
+namespace ns4 {
+template < typename T> T* foo (T);
+template <> int* foo(int) = delete;
+template <> int* foo(int); //expected-note{{candidate}}
+
+int *IP = foo(2); //expected-error{{deleted}}
+double *DP = foo(3.14);
+} //end ns4
+
+namespace ns5 {
+template < typename T> T* foo (T);
+template <> int* foo(int); //expected-note{{previous}}
+template <> int* foo(int) = delete; //expected-error{{deleted definition must 
be first declaration}}
+
+} //end ns5
+
+
 } // end test_explicit_specializations_and_delete


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >