aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Parse/DeclSpec.h73
-rw-r--r--lib/Parse/ParseDecl.cpp17
-rw-r--r--lib/Parse/ParseDeclCXX.cpp2
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);