summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-04-16 07:05:22 +0000
committerDouglas Gregor <dgregor@apple.com>2012-04-16 07:05:22 +0000
commitcefc3afac14d29de5aba7810cc8fe6c858949e9d (patch)
tree1ebfb2a0c67f5e253edc1a2900cdda348163f4f5 /include
parent275a8505420733a9e4c662289f36522a1dabaa51 (diff)
Implement C++11 [expr.prim.general]p3, which permits the use of 'this'
in the declaration of a non-static member function after the (optional) cv-qualifier-seq, which in practice means in the exception specification and late-specified return type. The new scheme here used to manage 'this' outside of a member function scope is more general than the Scope-based mechanism previously used for non-static data member initializers and late-parsesd attributes, because it can also handle the cv-qualifiers on the member function. Note, however, that a separate pass is required for static member functions to determine whether 'this' was used, because we might not know that we have a static function until after declaration matching. Finally, this introduces name mangling for 'this' and for the implicit 'this', which is intended to match GCC's mangling. Independent verification for the new mangling test case would be appreciated. Fixes PR10036 and PR12450. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154799 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--include/clang/Sema/Scope.h7
-rw-r--r--include/clang/Sema/Sema.h53
3 files changed, 53 insertions, 10 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b6b6398da9..48c48722f3 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3801,6 +3801,9 @@ def warn_null_in_comparison_operation : Warning<
def err_invalid_this_use : Error<
"invalid use of 'this' outside of a non-static member function">;
+def err_this_static_member_func : Error<
+ "'this' cannot be%select{| implicitly}0 used in a static member function "
+ "declaration">;
def err_invalid_member_use_in_static_method : Error<
"invalid use of member %0 in static member function">;
def err_invalid_qualified_function_type : Error<
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index e9aa173cb9..48f54179ec 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -81,13 +81,8 @@ public:
/// SwitchScope - This is a scope that corresponds to a switch statement.
SwitchScope = 0x800,
- /// ThisScope - This is the scope of a struct/union/class definition,
- /// outside of any member function definition, where 'this' is nonetheless
- /// usable.
- ThisScope = 0x1000,
-
/// TryScope - This is the scope of a C++ try statement.
- TryScope = 0x2000
+ TryScope = 0x1000
};
private:
/// The parent scope for this scope. This is null for the translation-unit
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index e8a9ff6971..2427a757dc 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -446,11 +446,13 @@ public:
Sema &S;
DeclContext *SavedContext;
ProcessingContextState SavedContextState;
-
+ QualType SavedCXXThisTypeOverride;
+
public:
ContextRAII(Sema &S, DeclContext *ContextToPush)
: S(S), SavedContext(S.CurContext),
- SavedContextState(S.DelayedDiagnostics.pushContext())
+ SavedContextState(S.DelayedDiagnostics.pushContext()),
+ SavedCXXThisTypeOverride(S.CXXThisTypeOverride)
{
assert(ContextToPush && "pushing null context");
S.CurContext = ContextToPush;
@@ -460,6 +462,7 @@ public:
if (!SavedContext) return;
S.CurContext = SavedContext;
S.DelayedDiagnostics.popContext(SavedContextState);
+ S.CXXThisTypeOverride = SavedCXXThisTypeOverride;
SavedContext = 0;
}
@@ -646,7 +649,7 @@ public:
/// A stack of expression evaluation contexts.
SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
-
+
/// SpecialMemberOverloadResult - The overloading result for a special member
/// function.
///
@@ -3247,6 +3250,18 @@ public:
/// special member function.
bool isImplicitlyDeleted(FunctionDecl *FD);
+ /// \brief Check wither 'this' shows up in the type of a static member
+ /// function after the (naturally empty) cv-qualifier-seq would be.
+ ///
+ /// \returns true if an error occurred.
+ bool checkThisInStaticMemberFunctionType(CXXMethodDecl *Method);
+
+ /// \brief Check wither 'this' shows up in the attributes of the given
+ /// static member function.
+ ///
+ /// \returns true if an error occurred.
+ bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method);
+
/// MaybeBindToTemporary - If the passed in expression has a record type with
/// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise
/// it simply returns the passed in expression.
@@ -3328,6 +3343,29 @@ public:
/// \returns The type of 'this', if possible. Otherwise, returns a NULL type.
QualType getCurrentThisType();
+ /// \brief When non-NULL, the C++ 'this' expression is allowed despite the
+ /// current context not being a non-static member function. In such cases,
+ /// this provides the type used for 'this'.
+ QualType CXXThisTypeOverride;
+
+ /// \brief RAII object used to temporarily allow the C++ 'this' expression
+ /// to be used, with the given qualifiers on the current class type.
+ class CXXThisScopeRAII {
+ Sema &S;
+ QualType OldCXXThisTypeOverride;
+ bool Enabled;
+
+ public:
+ /// \brief Introduce a new scope where 'this' may be allowed (when enabled),
+ /// using the given declaration (which is either a class template or a
+ /// class) along with the given qualifiers.
+ /// along with the qualifiers placed on '*this'.
+ CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals,
+ bool Enabled = true);
+
+ ~CXXThisScopeRAII();
+ };
+
/// \brief Make sure the value of 'this' is actually available in the current
/// context, if it is a potentially evaluated context.
///
@@ -3337,6 +3375,11 @@ public:
/// capture list.
void CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false);
+ /// \brief Determine whether the given type is the type of *this that is used
+ /// outside of the body of a member function for a type that is currently
+ /// being defined.
+ bool isThisOutsideMemberFunctionBody(QualType BaseType);
+
/// ActOnCXXBoolLiteral - Parse {true,false} literals.
ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
@@ -5481,7 +5524,9 @@ public:
TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T,
const MultiLevelTemplateArgumentList &TemplateArgs,
SourceLocation Loc,
- DeclarationName Entity);
+ DeclarationName Entity,
+ CXXRecordDecl *ThisContext,
+ unsigned ThisTypeQuals);
ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
const MultiLevelTemplateArgumentList &TemplateArgs,
int indexAdjustment,