[cfe-commits] r67140 - in /cfe/trunk/lib/Sema: Sema.h SemaCXXScopeSpec.cpp SemaDecl.cpp SemaDeclCXX.cpp SemaExpr.cpp SemaLookup.cpp SemaTemplate.cpp SemaType.cpp
Douglas Gregor
dgregor at apple.com
Tue Mar 17 17:36:05 PDT 2009
Author: dgregor
Date: Tue Mar 17 19:36:05 2009
New Revision: 67140
URL: http://llvm.org/viewvc/llvm-project?rev=67140&view=rev
Log:
The scope representation can now be either a DeclContext pointer or a
Type pointer. This allows our nested-name-specifiers to retain more
information about the actual spelling (e.g., which typedef did the
user name, or what exact template arguments were used in the
template-id?). It will also allow us to have dependent
nested-name-specifiers that don't map to any DeclContext.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaType.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=67140&r1=67139&r2=67140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Mar 17 19:36:05 2009
@@ -1452,6 +1452,21 @@
bool RequireCompleteDeclContext(const CXXScopeSpec &SS);
+ /// \brief Build a scope representation from a declaration context.
+ CXXScopeTy *createScopeRep(DeclContext *DC) {
+ return static_cast<CXXScopeTy *>(DC);
+ }
+
+ /// \brief Build a scope representation from a type.
+ CXXScopeTy *createScopeRep(QualType T);
+
+ DeclContext *getScopeRepAsDeclContext(const CXXScopeSpec &SS);
+ QualType getScopeRepAsType(const CXXScopeSpec &SS);
+
+ /// \brief Determines whether this scope specifier is represented as
+ /// a type.
+ bool isScopeRepType(const CXXScopeSpec &SS);
+
/// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
/// global scope ('::').
virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S,
Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=67140&r1=67139&r2=67140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Tue Mar 17 19:36:05 2009
@@ -17,6 +17,49 @@
#include "llvm/ADT/STLExtras.h"
using namespace clang;
+/// \brief Retrieve the scope represented by this scope specifier as a
+/// DeclContext.
+DeclContext *Sema::getScopeRepAsDeclContext(const CXXScopeSpec &SS) {
+ if (SS.isInvalid() || !SS.getScopeRep())
+ return 0;
+ uintptr_t Rep = reinterpret_cast<uintptr_t>(SS.getScopeRep());
+ if ((Rep & 0x01) == 0)
+ return reinterpret_cast<DeclContext *>(Rep);
+
+ // Retrieve the DeclContext associated with this type.
+ QualType T = QualType(reinterpret_cast<Type *>(Rep & ~0x01), 0);
+ const TagType *TagT = T->getAsTagType();
+ assert(TagT && "No DeclContext from a non-tag type");
+ return TagT->getDecl();
+}
+
+/// \brief Retrieve the scope represented by this scope specifier as a
+/// type.
+QualType Sema::getScopeRepAsType(const CXXScopeSpec &SS) {
+ if (SS.isInvalid() || !SS.getScopeRep())
+ return QualType();
+
+ uintptr_t Rep = reinterpret_cast<uintptr_t>(SS.getScopeRep());
+ if ((Rep & 0x01) == 0)
+ return QualType();
+ return QualType(reinterpret_cast<Type *>(Rep & ~0x01), 0);
+}
+
+Action::CXXScopeTy *Sema::createScopeRep(QualType T) {
+ assert(((reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()) & 0x01) == 0) &&
+ "Scope type with cv-qualifiers");
+ if (T.isNull())
+ return 0;
+
+ return reinterpret_cast<CXXScopeTy *>(
+ reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()) | 0x01);
+}
+
+bool Sema::isScopeRepType(const CXXScopeSpec &SS) {
+ uintptr_t Rep = reinterpret_cast<uintptr_t>(SS.getScopeRep());
+ return Rep & 0x01;
+}
+
/// \brief Require that the context specified by SS be complete.
///
/// If SS refers to a type, this routine checks whether the type is
@@ -30,7 +73,7 @@
if (!SS.isSet() || SS.isInvalid())
return false;
- DeclContext *DC = static_cast<DeclContext *>(SS.getScopeRep());
+ DeclContext *DC = getScopeRepAsDeclContext(SS);
if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
// If we're currently defining this type, then lookup into the
// type is okay: don't complain that it isn't complete yet.
@@ -52,7 +95,7 @@
/// global scope ('::').
Sema::CXXScopeTy *Sema::ActOnCXXGlobalScopeSpecifier(Scope *S,
SourceLocation CCLoc) {
- return cast<DeclContext>(Context.getTranslationUnitDecl());
+ return createScopeRep(Context.getTranslationUnitDecl());
}
/// ActOnCXXNestedNameSpecifier - Called during parsing of a
@@ -70,10 +113,10 @@
if (SD) {
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
- if (const RecordType* Record = TD->getUnderlyingType()->getAsRecordType())
- return cast<DeclContext>(Record->getDecl());
+ if (TD->getUnderlyingType()->isRecordType())
+ return createScopeRep(Context.getTypeDeclType(TD));
} else if (isa<NamespaceDecl>(SD) || isa<RecordDecl>(SD)) {
- return cast<DeclContext>(SD);
+ return createScopeRep(cast<DeclContext>(SD));
}
// FIXME: Template parameters and dependent types.
@@ -109,10 +152,7 @@
TypeTy *Ty,
SourceRange TypeRange,
SourceLocation CCLoc) {
- QualType Type = QualType::getFromOpaquePtr(Ty);
- assert(Type->isRecordType() &&
- "Types in a nested-name-specifier always refer to a record type");
- return cast<DeclContext>(Type->getAsRecordType()->getDecl());
+ return createScopeRep(QualType::getFromOpaquePtr(Ty));
}
/// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
@@ -125,7 +165,7 @@
assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
assert(PreDeclaratorDC == 0 && "Previous declarator context not popped?");
PreDeclaratorDC = static_cast<DeclContext*>(S->getEntity());
- CurContext = static_cast<DeclContext*>(SS.getScopeRep());
+ CurContext = getScopeRepAsDeclContext(SS);
S->setEntity(CurContext);
}
@@ -136,7 +176,8 @@
/// defining scope.
void Sema::ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
- assert(S->getEntity() == SS.getScopeRep() && "Context imbalance!");
+ assert(S->getEntity() == getScopeRepAsDeclContext(SS) &&
+ "Context imbalance!");
S->setEntity(PreDeclaratorDC);
PreDeclaratorDC = 0;
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=67140&r1=67139&r2=67140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Mar 17 19:36:05 2009
@@ -1257,7 +1257,7 @@
DeclSpec::SCS_static,
D.getIdentifierLoc());
} else { // Something like "int foo::x;"
- DC = static_cast<DeclContext*>(D.getCXXScopeSpec().getScopeRep());
+ DC = getScopeRepAsDeclContext(D.getCXXScopeSpec());
// FIXME: RequireCompleteDeclContext(D.getCXXScopeSpec()); ?
PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true);
@@ -3020,7 +3020,7 @@
}
// FIXME: RequireCompleteDeclContext(SS)?
- DC = static_cast<DeclContext*>(SS.getScopeRep());
+ DC = getScopeRepAsDeclContext(SS);
SearchDC = DC;
// Look-up name inside 'foo::'.
PrevDecl = dyn_cast_or_null<TagDecl>(
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=67140&r1=67139&r2=67140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Mar 17 19:36:05 2009
@@ -300,7 +300,7 @@
const CXXScopeSpec *SS) {
CXXRecordDecl *CurDecl;
if (SS) {
- DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
+ DeclContext *DC = getScopeRepAsDeclContext(*SS);
CurDecl = dyn_cast_or_null<CXXRecordDecl>(DC);
} else
CurDecl = dyn_cast_or_null<CXXRecordDecl>(CurContext);
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=67140&r1=67139&r2=67140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Mar 17 19:36:05 2009
@@ -727,7 +727,7 @@
// implicit member ref, because we want a pointer to the member in general,
// not any specific instance's member.
if (isAddressOfOperand && SS && !SS->isEmpty() && !HasTrailingLParen) {
- DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
+ DeclContext *DC = getScopeRepAsDeclContext(*SS);
if (D && isa<CXXRecordDecl>(DC)) {
QualType DType;
if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
@@ -942,7 +942,7 @@
// - a nested-name-specifier that contains a class-name that
// names a dependent type.
else if (SS && !SS->isEmpty()) {
- for (DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
+ for (DeclContext *DC = getScopeRepAsDeclContext(*SS);
DC; DC = DC->getParent()) {
// FIXME: could stop early at namespace scope.
if (DC->isRecord()) {
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=67140&r1=67139&r2=67140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Mar 17 19:36:05 2009
@@ -1039,7 +1039,7 @@
return LookupResult::CreateLookupResult(Context, 0);
if (SS->isSet())
- return LookupQualifiedName(static_cast<DeclContext *>(SS->getScopeRep()),
+ return LookupQualifiedName(getScopeRepAsDeclContext(*SS),
Name, NameKind, RedeclarationOnly);
}
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=67140&r1=67139&r2=67140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Mar 17 19:36:05 2009
@@ -399,7 +399,7 @@
DeclContext *SemanticContext = CurContext;
if (SS.isNotEmpty() && !SS.isInvalid()) {
- SemanticContext = static_cast<DeclContext*>(SS.getScopeRep());
+ SemanticContext = getScopeRepAsDeclContext(SS);
// FIXME: need to match up several levels of template parameter
// lists here.
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=67140&r1=67139&r2=67140&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Mar 17 19:36:05 2009
@@ -742,8 +742,7 @@
}
case DeclaratorChunk::MemberPointer:
// The scope spec must refer to a class, or be dependent.
- DeclContext *DC = static_cast<DeclContext*>(
- DeclType.Mem.Scope().getScopeRep());
+ DeclContext *DC = getScopeRepAsDeclContext(DeclType.Mem.Scope());
QualType ClsType;
// FIXME: Extend for dependent types when it's actually supported.
// See ActOnCXXNestedNameSpecifier.
More information about the cfe-commits
mailing list