[cfe-commits] r78286 - in /cfe/trunk/lib/Sema: SemaExpr.cpp SemaTemplateInstantiate.cpp TreeTransform.h
Douglas Gregor
dgregor at apple.com
Wed Aug 5 22:28:42 PDT 2009
Author: dgregor
Date: Thu Aug 6 00:28:30 2009
New Revision: 78286
URL: http://llvm.org/viewvc/llvm-project?rev=78286&view=rev
Log:
Implement transformation of nested-name-specifiers within the general
tree transformation. Template instantiation uses this general
transformation rather than implementing its own transformation.
Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/TreeTransform.h
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=78286&r1=78285&r2=78286&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Aug 6 00:28:30 2009
@@ -2181,8 +2181,7 @@
= LookupQualifiedName(DC, DeclarationName(&Member),
LookupMemberName, false);
- if (SS && SS->isSet())
- {
+ if (SS && SS->isSet()) {
QualType BaseTypeCanon
= Context.getCanonicalType(BaseType).getUnqualifiedType();
QualType MemberTypeCanon
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=78286&r1=78285&r2=78286&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Aug 6 00:28:30 2009
@@ -324,10 +324,6 @@
/// this declaration.
Decl *TransformDecl(Decl *D);
- /// \brief Transform the given nested-name-specifier by instantiating it.
- NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
- SourceRange Range);
-
/// \brief Transform the given template name by instantiating it.
TemplateName TransformTemplateName(TemplateName Template);
@@ -345,12 +341,6 @@
return SemaRef.InstantiateCurrentDeclRef(cast_or_null<NamedDecl>(D));
}
-NestedNameSpecifier *
-TemplateInstantiator::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
- SourceRange Range) {
- return getSema().InstantiateNestedNameSpecifier(NNS, Range, TemplateArgs);
-}
-
TemplateName
TemplateInstantiator::TransformTemplateName(TemplateName Template) {
return getSema().InstantiateTemplateName(Template, /*FIXME*/Loc,
@@ -722,59 +712,9 @@
Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
SourceRange Range,
const TemplateArgumentList &TemplateArgs) {
- // Instantiate the prefix of this nested name specifier.
- NestedNameSpecifier *Prefix = NNS->getPrefix();
- if (Prefix) {
- Prefix = InstantiateNestedNameSpecifier(Prefix, Range, TemplateArgs);
- if (!Prefix)
- return 0;
- }
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier: {
- assert(Prefix &&
- "Can't have an identifier nested-name-specifier with no prefix");
- CXXScopeSpec SS;
- // FIXME: The source location information is all wrong.
- SS.setRange(Range);
- SS.setScopeRep(Prefix);
- return static_cast<NestedNameSpecifier *>(
- ActOnCXXNestedNameSpecifier(0, SS,
- Range.getEnd(),
- Range.getEnd(),
- *NNS->getAsIdentifier()));
- break;
- }
-
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::Global:
- return NNS;
-
- case NestedNameSpecifier::TypeSpecWithTemplate:
- case NestedNameSpecifier::TypeSpec: {
- QualType T = QualType(NNS->getAsType(), 0);
- if (!T->isDependentType())
- return NNS;
-
- T = InstantiateType(T, TemplateArgs, Range.getBegin(), DeclarationName());
- if (T.isNull())
- return 0;
-
- if (T->isDependentType() || T->isRecordType() ||
- (getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
- assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
- return NestedNameSpecifier::Create(Context, Prefix,
- NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
- T.getTypePtr());
- }
-
- Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
- return 0;
- }
- }
-
- // Required to silence a GCC warning
- return 0;
+ TemplateInstantiator Instantiator(*this, TemplateArgs, Range.getBegin(),
+ DeclarationName());
+ return Instantiator.TransformNestedNameSpecifier(NNS, Range);
}
TemplateName
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=78286&r1=78285&r2=78286&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Aug 6 00:28:30 2009
@@ -14,6 +14,7 @@
#define LLVM_CLANG_SEMA_TREETRANSFORM_H
#include "Sema.h"
+#include "clang/Sema/SemaDiagnostic.h"
#include <algorithm>
namespace clang {
@@ -156,12 +157,15 @@
/// \brief Transform the given declaration, which is referenced from a type
/// or expression.
///
- /// Subclasses must override this.
- Decl *TransformDecl(Decl *D);
+ /// By default, acts as the identity function on declarations. Subclasses
+ /// may override this function to provide alternate behavior.
+ Decl *TransformDecl(Decl *D) { return D; }
/// \brief Transform the given nested-name-specifier.
///
- /// Subclasses must override this.
+ /// By default, transforms all of the types and declarations within the
+ /// nested-name-specifier. Subclasses may override this function to provide
+ /// alternate behavior.
NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
SourceRange Range);
@@ -397,10 +401,98 @@
const IdentifierInfo *Id) {
return SemaRef.CheckTypenameType(NNS, *Id,
SourceRange(getDerived().getBaseLocation()));
- }
+ }
+
+ /// \brief Build a new nested-name-specifier given the prefix and an
+ /// identifier that names the next step in the nested-name-specifier.
+ ///
+ /// By default, performs semantic analysis when building the new
+ /// nested-name-specifier. Subclasses may override this routine to provide
+ /// different behavior.
+ NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+ SourceRange Range,
+ IdentifierInfo &II);
+
+ /// \brief Build a new nested-name-specifier given the prefix and the
+ /// namespace named in the next step in the nested-name-specifier.
+ ///
+ /// By default, performs semantic analysis when building the new
+ /// nested-name-specifier. Subclasses may override this routine to provide
+ /// different behavior.
+ NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+ SourceRange Range,
+ NamespaceDecl *NS);
+
+ /// \brief Build a new nested-name-specifier given the prefix and the
+ /// type named in the next step in the nested-name-specifier.
+ ///
+ /// By default, performs semantic analysis when building the new
+ /// nested-name-specifier. Subclasses may override this routine to provide
+ /// different behavior.
+ NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+ SourceRange Range,
+ bool TemplateKW,
+ QualType T);
};
template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
+ SourceRange Range) {
+ // Instantiate the prefix of this nested name specifier.
+ NestedNameSpecifier *Prefix = NNS->getPrefix();
+ if (Prefix) {
+ Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range);
+ if (!Prefix)
+ return 0;
+ }
+
+ switch (NNS->getKind()) {
+ case NestedNameSpecifier::Identifier:
+ assert(Prefix &&
+ "Can't have an identifier nested-name-specifier with no prefix");
+ if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix())
+ return NNS;
+
+ return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
+ *NNS->getAsIdentifier());
+
+ case NestedNameSpecifier::Namespace: {
+ NamespaceDecl *NS
+ = cast_or_null<NamespaceDecl>(
+ getDerived().TransformDecl(NNS->getAsNamespace()));
+ if (!getDerived().AlwaysRebuild() &&
+ Prefix == NNS->getPrefix() &&
+ NS == NNS->getAsNamespace())
+ return NNS;
+
+ return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
+ }
+
+ case NestedNameSpecifier::Global:
+ // There is no meaningful transformation that one could perform on the
+ // global scope.
+ return NNS;
+
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ case NestedNameSpecifier::TypeSpec: {
+ QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
+ if (!getDerived().AlwaysRebuild() &&
+ Prefix == NNS->getPrefix() &&
+ T == QualType(NNS->getAsType(), 0))
+ return NNS;
+
+ return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
+ NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
+ T);
+ }
+ }
+
+ // Required to silence a GCC warning
+ return 0;
+}
+
+template<typename Derived>
TemplateArgument
TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
switch (Arg.getKind()) {
@@ -1212,6 +1304,45 @@
SourceLocation());
}
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+ SourceRange Range,
+ IdentifierInfo &II) {
+ CXXScopeSpec SS;
+ // FIXME: The source location information is all wrong.
+ SS.setRange(Range);
+ SS.setScopeRep(Prefix);
+ return static_cast<NestedNameSpecifier *>(
+ SemaRef.ActOnCXXNestedNameSpecifier(0, SS, Range.getEnd(),
+ Range.getEnd(), II));
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+ SourceRange Range,
+ NamespaceDecl *NS) {
+ return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+ SourceRange Range,
+ bool TemplateKW,
+ QualType T) {
+ if (T->isDependentType() || T->isRecordType() ||
+ (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
+ assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
+ return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
+ T.getTypePtr());
+ }
+
+ SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
+ return 0;
+}
+
} // end namespace clang
#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H
More information about the cfe-commits
mailing list