[cfe-commits] r126346 - in /cfe/trunk: include/clang/Sema/DeclSpec.h include/clang/Sema/Sema.h lib/Parse/ParseExprCXX.cpp lib/Sema/DeclSpec.cpp lib/Sema/SemaCXXScopeSpec.cpp lib/Sema/TreeTransform.h lib/Sema/TypeLocBuilder.h
Douglas Gregor
dgregor at apple.com
Wed Feb 23 16:17:56 PST 2011
Author: dgregor
Date: Wed Feb 23 18:17:56 2011
New Revision: 126346
URL: http://llvm.org/viewvc/llvm-project?rev=126346&view=rev
Log:
Teach CXXScopeSpec to handle the extension of a nested-name-specifier
with another component in the nested-name-specifiers, updating its
representation (a NestedNameSpecifier) and source-location information
(currently a SourceRange) simultaneously. This is groundwork for
adding source-location information to nested-name-specifiers.
Modified:
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/lib/Sema/TypeLocBuilder.h
Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=126346&r1=126345&r2=126346&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Wed Feb 23 18:17:56 2011
@@ -29,9 +29,12 @@
#include "llvm/Support/ErrorHandling.h"
namespace clang {
+ class ASTContext;
+ class TypeLoc;
class LangOptions;
class Diagnostic;
class IdentifierInfo;
+ class NamespaceDecl;
class NestedNameSpecifier;
class Preprocessor;
class Declarator;
@@ -51,7 +54,7 @@
class CXXScopeSpec {
SourceRange Range;
NestedNameSpecifier *ScopeRep;
-
+
public:
CXXScopeSpec() : Range(), ScopeRep() { }
@@ -65,6 +68,54 @@
NestedNameSpecifier *getScopeRep() const { return ScopeRep; }
void setScopeRep(NestedNameSpecifier *S) { ScopeRep = S; }
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'type::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param TemplateKWLoc The location of the 'template' keyword, if present.
+ ///
+ /// \param TL The TypeLoc that describes the type preceding the '::'.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
+ SourceLocation ColonColonLoc);
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'identifier::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param Identifier The identifier.
+ ///
+ /// \param IdentifierLoc The location of the identifier.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, IdentifierInfo *Identifier,
+ SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'namespace-or-alias::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param Namespace The namespace.
+ /// FIXME: This should also permit a namespace alias.
+ ///
+ /// \param NamespaceLoc The location of the namespace or namespace alias
+ /// name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, NamespaceDecl *Namespace,
+ SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
+
+ /// \brief Turn this (empty) nested-name-specifier into the global
+ /// nested-name-specifier '::'.
+ void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
+
/// No scope specifier.
bool isEmpty() const { return !Range.isValid(); }
/// A scope specifier is present, but may be valid or invalid.
@@ -75,6 +126,15 @@
/// A scope specifier is present, and it refers to a real scope.
bool isValid() const { return isNotEmpty() && ScopeRep != 0; }
+ /// \brief Indicate that this nested-name-specifier is invalid.
+ void SetInvalid(SourceRange R) {
+ assert(R.isValid() && "Must have a valid source range");
+ if (Range.getBegin().isInvalid())
+ Range.setBegin(R.getBegin());
+ Range.setEnd(R.getEnd());
+ ScopeRep = 0;
+ }
+
/// Deprecated. Some call sites intend isNotEmpty() while others intend
/// isValid().
bool isSet() const { return ScopeRep != 0; }
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=126346&r1=126345&r2=126346&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Feb 23 18:17:56 2011
@@ -2591,11 +2591,19 @@
CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
bool isUnknownSpecialization(const CXXScopeSpec &SS);
- /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
- /// global scope ('::').
- NestedNameSpecifier *
- ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc);
-
+ /// \brief The parser has parsed a global nested-name-specifier '::'.
+ ///
+ /// \param S The scope in which this nested-name-specifier occurs.
+ ///
+ /// \param CCLoc The location of the '::'.
+ ///
+ /// \param SS The nested-name-specifier, which will be updated in-place
+ /// to reflect the parsed nested-name-specifier.
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
+ CXXScopeSpec &SS);
+
bool isAcceptableNestedNameSpecifier(NamedDecl *SD);
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
@@ -2604,42 +2612,72 @@
IdentifierInfo &II,
ParsedType ObjectType);
- NestedNameSpecifier *BuildCXXNestedNameSpecifier(Scope *S,
- CXXScopeSpec &SS,
- SourceLocation IdLoc,
- SourceLocation CCLoc,
- IdentifierInfo &II,
- QualType ObjectType,
- NamedDecl *ScopeLookupResult,
- bool EnteringContext,
- bool ErrorRecoveryLookup);
-
- NestedNameSpecifier *ActOnCXXNestedNameSpecifier(Scope *S,
- CXXScopeSpec &SS,
- SourceLocation IdLoc,
- SourceLocation CCLoc,
- IdentifierInfo &II,
- ParsedType ObjectType,
- bool EnteringContext);
+ bool BuildCXXNestedNameSpecifier(Scope *S,
+ IdentifierInfo &Identifier,
+ SourceLocation IdentifierLoc,
+ SourceLocation CCLoc,
+ QualType ObjectType,
+ bool EnteringContext,
+ CXXScopeSpec &SS,
+ NamedDecl *ScopeLookupResult,
+ bool ErrorRecoveryLookup);
+
+ /// \brief The parser has parsed a nested-name-specifier 'identifier::'.
+ ///
+ /// \param S The scope in which this nested-name-specifier occurs.
+ ///
+ /// \param Identifier The identifier preceding the '::'.
+ ///
+ /// \param IdentifierLoc The location of the identifier.
+ ///
+ /// \param CCLoc The location of the '::'.
+ ///
+ /// \param ObjectType The type of the object, if we're parsing
+ /// nested-name-specifier in a member access expression.
+ ///
+ /// \param EnteringContext Whether we're entering the context nominated by
+ /// this nested-name-specifier.
+ ///
+ /// \param SS The nested-name-specifier, which is both an input
+ /// parameter (the nested-name-specifier before this type) and an
+ /// output parameter (containing the full nested-name-specifier,
+ /// including this new type).
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool ActOnCXXNestedNameSpecifier(Scope *S,
+ IdentifierInfo &Identifier,
+ SourceLocation IdentifierLoc,
+ SourceLocation CCLoc,
+ ParsedType ObjectType,
+ bool EnteringContext,
+ CXXScopeSpec &SS);
bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
- IdentifierInfo &II,
+ IdentifierInfo &Identifier,
+ SourceLocation IdentifierLoc,
+ SourceLocation ColonLoc,
ParsedType ObjectType,
bool EnteringContext);
- /// ActOnCXXNestedNameSpecifier - Called during parsing of a
- /// nested-name-specifier that involves a template-id, e.g.,
- /// "foo::bar<int, float>::", and now we need to build a scope
- /// specifier. \p SS is empty or the previously parsed nested-name
- /// part ("foo::"), \p Type is the already-parsed class template
- /// specialization (or other template-id that names a type), \p
- /// TypeRange is the source range where the type is located, and \p
- /// CCLoc is the location of the trailing '::'.
- CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
- const CXXScopeSpec &SS,
- ParsedType Type,
- SourceRange TypeRange,
- SourceLocation CCLoc);
+ /// \brief The parser has parsed a nested-name-specifier 'type::'.
+ ///
+ /// \param S The scope in which this nested-name-specifier occurs.
+ ///
+ /// \param Type The type, which will be a template specialization
+ /// type, preceding the '::'.
+ ///
+ /// \param CCLoc The location of the '::'.
+ ///
+ /// \param SS The nested-name-specifier, which is both an input
+ /// parameter (the nested-name-specifier before this type) and an
+ /// output parameter (containing the full nested-name-specifier,
+ /// including this new type).
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool ActOnCXXNestedNameSpecifier(Scope *S,
+ ParsedType Type,
+ SourceLocation CCLoc,
+ CXXScopeSpec &SS);
bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=126346&r1=126345&r2=126346&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Feb 23 18:17:56 2011
@@ -80,10 +80,9 @@
return false;
// '::' - Global scope qualifier.
- SourceLocation CCLoc = ConsumeToken();
- SS.setBeginLoc(CCLoc);
- SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(getCurScope(), CCLoc));
- SS.setEndLoc(CCLoc);
+ if (Actions.ActOnCXXGlobalScopeSpecifier(getCurScope(), ConsumeToken(), SS))
+ return true;
+
HasScopeSpecifier = true;
}
@@ -214,14 +213,14 @@
}
if (ParsedType T = getTypeAnnotation(TypeToken)) {
- CXXScopeTy *Scope =
- Actions.ActOnCXXNestedNameSpecifier(getCurScope(), SS, T,
- TypeToken.getAnnotationRange(),
- CCLoc);
- SS.setScopeRep(Scope);
- } else
- SS.setScopeRep(0);
- SS.setEndLoc(CCLoc);
+ if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), T, CCLoc, SS))
+ SS.SetInvalid(SourceRange(SS.getBeginLoc(), CCLoc));
+
+ continue;
+ } else {
+ SS.SetInvalid(SourceRange(SS.getBeginLoc(), CCLoc));
+ }
+
continue;
}
@@ -245,7 +244,9 @@
// If we get foo:bar, this is almost certainly a typo for foo::bar. Recover
// and emit a fixit hint for it.
if (Next.is(tok::colon) && !ColonIsSacred) {
- if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, II, ObjectType,
+ if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, II,
+ Tok.getLocation(),
+ Next.getLocation(), ObjectType,
EnteringContext) &&
// If the token after the colon isn't an identifier, it's still an
// error, but they probably meant something else strange so don't
@@ -274,16 +275,11 @@
"NextToken() not working properly!");
SourceLocation CCLoc = ConsumeToken();
- if (!HasScopeSpecifier) {
- SS.setBeginLoc(IdLoc);
- HasScopeSpecifier = true;
- }
-
- if (!SS.isInvalid())
- SS.setScopeRep(
- Actions.ActOnCXXNestedNameSpecifier(getCurScope(), SS, IdLoc, CCLoc, II,
- ObjectType, EnteringContext));
- SS.setEndLoc(CCLoc);
+ HasScopeSpecifier = true;
+ if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc,
+ ObjectType, EnteringContext, SS))
+ SS.SetInvalid(SourceRange(IdLoc, CCLoc));
+
continue;
}
Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=126346&r1=126345&r2=126346&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Wed Feb 23 18:17:56 2011
@@ -14,6 +14,8 @@
#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ParsedTemplate.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TypeLoc.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/STLExtras.h"
@@ -44,6 +46,41 @@
EndLocation = TemplateId->RAngleLoc;
}
+void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc,
+ TypeLoc TL, SourceLocation ColonColonLoc) {
+ ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep,
+ TemplateKWLoc.isValid(),
+ TL.getTypePtr());
+ if (Range.getBegin().isInvalid())
+ Range.setBegin(TL.getBeginLoc());
+ Range.setEnd(ColonColonLoc);
+}
+
+void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
+ SourceLocation IdentifierLoc,
+ SourceLocation ColonColonLoc) {
+ ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep, Identifier);
+ if (Range.getBegin().isInvalid())
+ Range.setBegin(IdentifierLoc);
+ Range.setEnd(ColonColonLoc);
+}
+
+void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
+ SourceLocation NamespaceLoc,
+ SourceLocation ColonColonLoc) {
+ ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep, Namespace);
+ if (Range.getBegin().isInvalid())
+ Range.setBegin(NamespaceLoc);
+ Range.setEnd(ColonColonLoc);
+}
+
+void CXXScopeSpec::MakeGlobal(ASTContext &Context,
+ SourceLocation ColonColonLoc) {
+ assert(!ScopeRep && "Already have a nested-name-specifier!?");
+ ScopeRep = NestedNameSpecifier::GlobalSpecifier(Context);
+ Range = SourceRange(ColonColonLoc);
+}
+
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
/// "TheDeclarator" is the declarator that this will be added to.
DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=126346&r1=126345&r2=126346&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Wed Feb 23 18:17:56 2011
@@ -19,6 +19,7 @@
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Sema/DeclSpec.h"
+#include "TypeLocBuilder.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -219,7 +220,7 @@
Context.getTypeDeclType(Tag),
PDiag(diag::err_incomplete_nested_name_spec)
<< SS.getRange())) {
- SS.setScopeRep(0); // Mark the ScopeSpec invalid.
+ SS.SetInvalid(SS.getRange());
return true;
}
}
@@ -227,11 +228,10 @@
return false;
}
-/// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
-/// global scope ('::').
-Sema::CXXScopeTy *Sema::ActOnCXXGlobalScopeSpecifier(Scope *S,
- SourceLocation CCLoc) {
- return NestedNameSpecifier::GlobalSpecifier(Context);
+bool Sema::ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
+ CXXScopeSpec &SS) {
+ SS.MakeGlobal(Context, CCLoc);
+ return false;
}
/// \brief Determines whether the given declaration is an valid acceptable
@@ -352,22 +352,21 @@
///
/// If ErrorRecoveryLookup is true, then this call is used to improve error
/// recovery. This means that it should not emit diagnostics, it should
-/// just return null on failure. It also means it should only return a valid
+/// just return true on failure. It also means it should only return a valid
/// scope if it *knows* that the result is correct. It should not return in a
-/// dependent context, for example.
-Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
- CXXScopeSpec &SS,
- SourceLocation IdLoc,
- SourceLocation CCLoc,
- IdentifierInfo &II,
- QualType ObjectType,
- NamedDecl *ScopeLookupResult,
- bool EnteringContext,
- bool ErrorRecoveryLookup) {
- NestedNameSpecifier *Prefix
- = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
-
- LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
+/// dependent context, for example. Nor will it extend \p SS with the scope
+/// specifier.
+bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
+ IdentifierInfo &Identifier,
+ SourceLocation IdentifierLoc,
+ SourceLocation CCLoc,
+ QualType ObjectType,
+ bool EnteringContext,
+ CXXScopeSpec &SS,
+ NamedDecl *ScopeLookupResult,
+ bool ErrorRecoveryLookup) {
+ LookupResult Found(*this, &Identifier, IdentifierLoc,
+ LookupNestedNameSpecifierName);
// Determine where to perform name lookup
DeclContext *LookupCtx = 0;
@@ -397,7 +396,7 @@
// The declaration context must be complete.
if (!LookupCtx->isDependentContext() &&
RequireCompleteDeclContext(SS, LookupCtx))
- return 0;
+ return true;
LookupQualifiedName(Found, LookupCtx);
@@ -442,16 +441,14 @@
!cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()))) {
// Don't speculate if we're just trying to improve error recovery.
if (ErrorRecoveryLookup)
- return 0;
+ return true;
// We were not able to compute the declaration context for a dependent
// base object type or prior nested-name-specifier, so this
// nested-name-specifier refers to an unknown specialization. Just build
// a dependent nested-name-specifier.
- if (!Prefix)
- return NestedNameSpecifier::Create(Context, &II);
-
- return NestedNameSpecifier::Create(Context, Prefix, &II);
+ SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
+ return false;
}
// FIXME: Deal with ambiguities cleanly.
@@ -480,7 +477,7 @@
<< ND->getDeclName();
} else {
Found.clear();
- Found.setLookupName(&II);
+ Found.setLookupName(&Identifier);
}
}
@@ -497,7 +494,8 @@
// scope, reconstruct the result from the template instantiation itself.
NamedDecl *OuterDecl;
if (S) {
- LookupResult FoundOuter(*this, &II, IdLoc, LookupNestedNameSpecifierName);
+ LookupResult FoundOuter(*this, &Identifier, IdentifierLoc,
+ LookupNestedNameSpecifierName);
LookupName(FoundOuter, S);
OuterDecl = FoundOuter.getAsSingle<NamedDecl>();
} else
@@ -509,39 +507,75 @@
!Context.hasSameType(
Context.getTypeDeclType(cast<TypeDecl>(OuterDecl)),
Context.getTypeDeclType(cast<TypeDecl>(SD))))) {
- if (ErrorRecoveryLookup)
- return 0;
-
- Diag(IdLoc, diag::err_nested_name_member_ref_lookup_ambiguous)
- << &II;
- Diag(SD->getLocation(), diag::note_ambig_member_ref_object_type)
- << ObjectType;
- Diag(OuterDecl->getLocation(), diag::note_ambig_member_ref_scope);
-
- // Fall through so that we'll pick the name we found in the object
- // type, since that's probably what the user wanted anyway.
- }
+ if (ErrorRecoveryLookup)
+ return true;
+
+ Diag(IdentifierLoc,
+ diag::err_nested_name_member_ref_lookup_ambiguous)
+ << &Identifier;
+ Diag(SD->getLocation(), diag::note_ambig_member_ref_object_type)
+ << ObjectType;
+ Diag(OuterDecl->getLocation(), diag::note_ambig_member_ref_scope);
+
+ // Fall through so that we'll pick the name we found in the object
+ // type, since that's probably what the user wanted anyway.
+ }
}
- if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD))
- return NestedNameSpecifier::Create(Context, Prefix, Namespace);
+ // If we're just performing this lookup for error-recovery purposes,
+ // don't extend the nested-name-specifier. Just return now.
+ if (ErrorRecoveryLookup)
+ return false;
+
+ if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD)) {
+ SS.Extend(Context, Namespace, IdentifierLoc, CCLoc);
+ return false;
+ }
// FIXME: It would be nice to maintain the namespace alias name, then
// see through that alias when resolving the nested-name-specifier down to
// a declaration context.
- if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(SD))
- return NestedNameSpecifier::Create(Context, Prefix,
- Alias->getNamespace());
+ if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(SD)) {
+ SS.Extend(Context, Alias->getNamespace(), IdentifierLoc, CCLoc);
+ return false;
+ }
QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD));
- return NestedNameSpecifier::Create(Context, Prefix, false,
- T.getTypePtr());
+ TypeLocBuilder TLB;
+ if (isa<InjectedClassNameType>(T)) {
+ InjectedClassNameTypeLoc InjectedTL
+ = TLB.push<InjectedClassNameTypeLoc>(T);
+ InjectedTL.setNameLoc(IdentifierLoc);
+ } else if (isa<RecordDecl>(SD)) {
+ RecordTypeLoc RecordTL = TLB.push<RecordTypeLoc>(T);
+ RecordTL.setNameLoc(IdentifierLoc);
+ } else if (isa<TypedefDecl>(SD)) {
+ TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(T);
+ TypedefTL.setNameLoc(IdentifierLoc);
+ } else if (isa<EnumDecl>(SD)) {
+ EnumTypeLoc EnumTL = TLB.push<EnumTypeLoc>(T);
+ EnumTL.setNameLoc(IdentifierLoc);
+ } else if (isa<TemplateTypeParmDecl>(SD)) {
+ TemplateTypeParmTypeLoc TemplateTypeTL
+ = TLB.push<TemplateTypeParmTypeLoc>(T);
+ TemplateTypeTL.setNameLoc(IdentifierLoc);
+ } else {
+ assert(isa<UnresolvedUsingTypenameDecl>(SD) &&
+ "Unhandled TypeDecl node in nested-name-specifier");
+ UnresolvedUsingTypeLoc UnresolvedTL
+ = TLB.push<UnresolvedUsingTypeLoc>(T);
+ UnresolvedTL.setNameLoc(IdentifierLoc);
+ }
+
+ SS.Extend(Context, SourceLocation(), TLB.getTypeLocInContext(Context, T),
+ CCLoc);
+ return false;
}
// Otherwise, we have an error case. If we don't want diagnostics, just
// return an error now.
if (ErrorRecoveryLookup)
- return 0;
+ return true;
// If we didn't find anything during our lookup, try again with
// ordinary name lookup, which can help us produce better error
@@ -555,36 +589,34 @@
if (!Found.empty())
DiagID = diag::err_expected_class_or_namespace;
else if (SS.isSet()) {
- Diag(IdLoc, diag::err_no_member) << &II << LookupCtx << SS.getRange();
- return 0;
+ Diag(IdentifierLoc, diag::err_no_member)
+ << &Identifier << LookupCtx << SS.getRange();
+ return true;
} else
DiagID = diag::err_undeclared_var_use;
if (SS.isSet())
- Diag(IdLoc, DiagID) << &II << SS.getRange();
+ Diag(IdentifierLoc, DiagID) << &Identifier << SS.getRange();
else
- Diag(IdLoc, DiagID) << &II;
+ Diag(IdentifierLoc, DiagID) << &Identifier;
- return 0;
+ return true;
}
-/// ActOnCXXNestedNameSpecifier - Called during parsing of a
-/// nested-name-specifier. e.g. for "foo::bar::" we parsed "foo::" and now
-/// we want to resolve "bar::". 'SS' is empty or the previously parsed
-/// nested-name part ("foo::"), 'IdLoc' is the source location of 'bar',
-/// 'CCLoc' is the location of '::' and 'II' is the identifier for 'bar'.
-/// Returns a CXXScopeTy* object representing the C++ scope.
-Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
- CXXScopeSpec &SS,
- SourceLocation IdLoc,
- SourceLocation CCLoc,
- IdentifierInfo &II,
- ParsedType ObjectTypePtr,
- bool EnteringContext) {
- return BuildCXXNestedNameSpecifier(S, SS, IdLoc, CCLoc, II,
- GetTypeFromParser(ObjectTypePtr),
- /*ScopeLookupResult=*/0, EnteringContext,
- false);
+bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
+ IdentifierInfo &Identifier,
+ SourceLocation IdentifierLoc,
+ SourceLocation CCLoc,
+ ParsedType ObjectType,
+ bool EnteringContext,
+ CXXScopeSpec &SS) {
+ if (SS.isInvalid())
+ return true;
+
+ return BuildCXXNestedNameSpecifier(S, Identifier, IdentifierLoc, CCLoc,
+ GetTypeFromParser(ObjectType),
+ EnteringContext, SS,
+ /*ScopeLookupResult=*/0, false);
}
/// IsInvalidUnlessNestedName - This method is used for error recovery
@@ -594,23 +626,36 @@
///
/// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
- IdentifierInfo &II, ParsedType ObjectType,
+ IdentifierInfo &Identifier,
+ SourceLocation IdentifierLoc,
+ SourceLocation ColonLoc,
+ ParsedType ObjectType,
bool EnteringContext) {
- return BuildCXXNestedNameSpecifier(S, SS, SourceLocation(), SourceLocation(),
- II, GetTypeFromParser(ObjectType),
- /*ScopeLookupResult=*/0, EnteringContext,
- true);
+ if (SS.isInvalid())
+ return false;
+
+ return !BuildCXXNestedNameSpecifier(S, Identifier, IdentifierLoc, ColonLoc,
+ GetTypeFromParser(ObjectType),
+ EnteringContext, SS,
+ /*ScopeLookupResult=*/0, true);
}
-Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
- const CXXScopeSpec &SS,
- ParsedType Ty,
- SourceRange TypeRange,
- SourceLocation CCLoc) {
- NestedNameSpecifier *Prefix = SS.getScopeRep();
- QualType T = GetTypeFromParser(Ty);
- return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
- T.getTypePtr());
+bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
+ ParsedType Type,
+ SourceLocation CCLoc,
+ CXXScopeSpec &SS) {
+ if (SS.isInvalid())
+ return true;
+
+ TypeSourceInfo *TSInfo;
+ QualType T = GetTypeFromParser(Type, &TSInfo);
+ if (T.isNull())
+ return true;
+
+ assert(TSInfo && "Not TypeSourceInfo in nested-name-specifier?");
+ // FIXME: location of the 'template' keyword?
+ SS.Extend(Context, SourceLocation(), TSInfo->getTypeLoc(), CCLoc);
+ return false;
}
bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=126346&r1=126345&r2=126346&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Wed Feb 23 18:17:56 2011
@@ -7559,12 +7559,14 @@
// FIXME: The source location information is all wrong.
SS.setRange(Range);
SS.setScopeRep(Prefix);
- return static_cast<NestedNameSpecifier *>(
- SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
- Range.getEnd(), II,
- ObjectType,
- FirstQualifierInScope,
- false, false));
+ if (SemaRef.BuildCXXNestedNameSpecifier(0, II, /*FIXME:*/Range.getBegin(),
+ /*FIXME:*/Range.getEnd(),
+ ObjectType, false,
+ SS, FirstQualifierInScope,
+ false))
+ return 0;
+
+ return SS.getScopeRep();
}
template<typename Derived>
Modified: cfe/trunk/lib/Sema/TypeLocBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TypeLocBuilder.h?rev=126346&r1=126345&r2=126346&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TypeLocBuilder.h (original)
+++ cfe/trunk/lib/Sema/TypeLocBuilder.h Wed Feb 23 18:17:56 2011
@@ -107,6 +107,19 @@
return DI;
}
+ /// \brief Copies the type-location information to the given AST context and
+ /// returns a \c TypeLoc referring into the AST context.
+ TypeLoc getTypeLocInContext(ASTContext &Context, QualType T) {
+#ifndef NDEBUG
+ assert(T == LastTy && "type doesn't match last type pushed!");
+#endif
+
+ size_t FullDataSize = Capacity - Index;
+ void *Mem = Context.Allocate(FullDataSize);
+ memcpy(Mem, &Buffer[Index], FullDataSize);
+ return TypeLoc(T, Mem);
+ }
+
private:
TypeLoc pushImpl(QualType T, size_t LocalSize) {
#ifndef NDEBUG
More information about the cfe-commits
mailing list