diff options
-rw-r--r-- | include/clang/Parse/DeclSpec.h | 73 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 17 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 2 |
3 files changed, 49 insertions, 43 deletions
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index fe899b3fdb..b766890b70 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -27,6 +27,40 @@ namespace clang { class Declarator; struct TemplateIdAnnotation; +/// CXXScopeSpec - Represents a C++ nested-name-specifier or a global scope +/// specifier. +class CXXScopeSpec { + SourceRange Range; + void *ScopeRep; + +public: + CXXScopeSpec() : Range(), ScopeRep() { } + + const SourceRange &getRange() const { return Range; } + void setRange(const SourceRange &R) { Range = R; } + void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); } + void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); } + SourceLocation getBeginLoc() const { return Range.getBegin(); } + SourceLocation getEndLoc() const { return Range.getEnd(); } + + ActionBase::CXXScopeTy *getScopeRep() const { return ScopeRep; } + void setScopeRep(ActionBase::CXXScopeTy *S) { ScopeRep = S; } + + bool isEmpty() const { return !Range.isValid(); } + bool isNotEmpty() const { return !isEmpty(); } + + /// isInvalid - An error occured during parsing of the scope specifier. + bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; } + + /// isSet - A scope specifier was resolved to a valid C++ scope. + bool isSet() const { return ScopeRep != 0; } + + void clear() { + Range = SourceRange(); + ScopeRep = 0; + } +}; + /// DeclSpec - This class captures information about "declaration specifiers", /// which encompasses storage-class-specifiers, type-specifiers, /// type-qualifiers, and function-specifiers. @@ -143,6 +177,9 @@ private: // attributes. AttributeList *AttrList; + // Scope specifier for the type spec, if applicable. + CXXScopeSpec TypeScope; + // List of protocol qualifiers for objective-c classes. Used for // protocol-qualified interfaces "NString<foo>" and protocol-qualified id // "id<foo>". @@ -211,6 +248,8 @@ public: TST getTypeSpecType() const { return (TST)TypeSpecType; } bool isTypeSpecOwned() const { return TypeSpecOwned; } void *getTypeRep() const { return TypeRep; } + CXXScopeSpec &getTypeSpecScope() { return TypeScope; } + const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; } const SourceRange &getSourceRange() const { return Range; } SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; } @@ -436,40 +475,6 @@ private: IdentifierInfo *SetterName; // setter name of NULL if no setter }; -/// CXXScopeSpec - Represents a C++ nested-name-specifier or a global scope -/// specifier. -class CXXScopeSpec { - SourceRange Range; - void *ScopeRep; - -public: - CXXScopeSpec() : Range(), ScopeRep() { } - - const SourceRange &getRange() const { return Range; } - void setRange(const SourceRange &R) { Range = R; } - void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); } - void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); } - SourceLocation getBeginLoc() const { return Range.getBegin(); } - SourceLocation getEndLoc() const { return Range.getEnd(); } - - ActionBase::CXXScopeTy *getScopeRep() const { return ScopeRep; } - void setScopeRep(ActionBase::CXXScopeTy *S) { ScopeRep = S; } - - bool isEmpty() const { return !Range.isValid(); } - bool isNotEmpty() const { return !isEmpty(); } - - /// isInvalid - An error occured during parsing of the scope specifier. - bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; } - - /// isSet - A scope specifier was resolved to a valid C++ scope. - bool isSet() const { return ScopeRep != 0; } - - void clear() { - Range = SourceRange(); - ScopeRep = 0; - } -}; - /// \brief Represents a C++ unqualified-id that has been parsed. class UnqualifiedId { private: diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index efac0c4a03..5dd78f7b54 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -824,14 +824,18 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (DS.hasTypeSpecifier()) goto DoneWithDeclSpec; + CXXScopeSpec SS; + SS.setScopeRep(Tok.getAnnotationValue()); + SS.setRange(Tok.getAnnotationRange()); + // We are looking for a qualified typename. Token Next = NextToken(); if (Next.is(tok::annot_template_id) && static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue()) ->Kind == TNK_Type_template) { // We have a qualified template-id, e.g., N::A<int> - CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); + DS.getTypeSpecScope() = SS; + ConsumeToken(); // The C++ scope. assert(Tok.is(tok::annot_template_id) && "ParseOptionalCXXScopeSpecifier not working"); AnnotateTemplateIdTokenAsType(&SS); @@ -839,8 +843,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, } if (Next.is(tok::annot_typename)) { - // FIXME: is this scope-specifier getting dropped? - ConsumeToken(); // the scope-specifier + DS.getTypeSpecScope() = SS; + ConsumeToken(); // The C++ scope. if (Tok.getAnnotationValue()) isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, @@ -854,10 +858,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (Next.isNot(tok::identifier)) goto DoneWithDeclSpec; - CXXScopeSpec SS; - SS.setScopeRep(Tok.getAnnotationValue()); - SS.setRange(Tok.getAnnotationRange()); - // If the next token is the name of the class type that the C++ scope // denotes, followed by a '(', then this is a constructor declaration. // We're done with the decl-specifiers. @@ -879,6 +879,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, goto DoneWithDeclSpec; } + DS.getTypeSpecScope() = SS; ConsumeToken(); // The C++ scope. isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 78336bbfb1..d4d19a0b07 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -600,7 +600,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, } // Parse the (optional) nested-name-specifier. - CXXScopeSpec SS; + CXXScopeSpec &SS = DS.getTypeSpecScope(); if (getLang().CPlusPlus) { // "FOO : BAR" is not a potential typo for "FOO::BAR". ColonProtectionRAIIObject X(*this); |