summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp23
-rw-r--r--clang/lib/AST/CMakeLists.txt1
-rw-r--r--clang/lib/AST/NestedNameSpecifier.cpp34
-rw-r--r--clang/lib/AST/Type.cpp63
-rw-r--r--clang/lib/AST/TypeSerialization.cpp15
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp1
-rw-r--r--clang/lib/Parse/DeclSpec.cpp61
-rw-r--r--clang/lib/Parse/ParseDecl.cpp5
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp11
-rw-r--r--clang/lib/Parse/Parser.cpp4
-rw-r--r--clang/lib/Sema/Sema.h17
-rw-r--r--clang/lib/Sema/SemaCXXScopeSpec.cpp64
-rw-r--r--clang/lib/Sema/SemaDecl.cpp26
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp4
-rw-r--r--clang/lib/Sema/SemaExpr.cpp4
-rw-r--r--clang/lib/Sema/SemaLookup.cpp5
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp8
-rw-r--r--clang/lib/Sema/SemaType.cpp5
19 files changed, 263 insertions, 90 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c318107dab3..c5441dd3041 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1375,6 +1375,29 @@ ASTContext::getClassTemplateSpecializationType(TemplateDecl *Template,
return QualType(Spec, 0);
}
+QualType
+ASTContext::getQualifiedNameType(const NestedNameSpecifier *Components,
+ unsigned NumComponents,
+ QualType NamedType) {
+ llvm::FoldingSetNodeID ID;
+ QualifiedNameType::Profile(ID, Components, NumComponents, NamedType);
+
+ void *InsertPos = 0;
+ QualifiedNameType *T
+ = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+ if (T)
+ return QualType(T, 0);
+
+ void *Mem = Allocate((sizeof(QualifiedNameType) +
+ sizeof(NestedNameSpecifier) * NumComponents),
+ 8);
+ T = new (Mem) QualifiedNameType(Components, NumComponents, NamedType,
+ getCanonicalType(NamedType));
+ Types.push_back(T);
+ QualifiedNameTypes.InsertNode(T, InsertPos);
+ return QualType(T, 0);
+}
+
/// CmpProtocolNames - Comparison predicate for sorting protocols
/// alphabetically.
static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,
diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 48b19711127..5ea7a47fd60 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -18,6 +18,7 @@ add_clang_library(clangAST
Expr.cpp
ExprCXX.cpp
InheritViz.cpp
+ NestedNameSpecifier.cpp
ParentMap.cpp
Stmt.cpp
StmtDumper.cpp
diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp
new file mode 100644
index 00000000000..318c05fe7ca
--- /dev/null
+++ b/clang/lib/AST/NestedNameSpecifier.cpp
@@ -0,0 +1,34 @@
+//===--- NestedNameSpecifier.cpp - C++ nested name specifiers -----*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the NestedNameSpecifier class, which represents
+// a C++ nested-name-specifier.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Type.h"
+using namespace clang;
+
+DeclContext *
+NestedNameSpecifier::computeDeclContext(ASTContext &Context) const {
+ // The simple case: we're storing a DeclContext
+ if ((Data & 0x01) == 0)
+ return reinterpret_cast<DeclContext *>(Data);
+
+ Type *T = getAsType();
+ if (!T)
+ return 0;
+
+ // Retrieve the DeclContext associated with this type.
+ const TagType *TagT = T->getAsTagType();
+ assert(TagT && "No DeclContext from a non-tag type");
+ return TagT->getDecl();
+}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index bb3df0882ff..b066802c67a 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -96,6 +96,8 @@ QualType Type::getDesugaredType() const {
if (const ClassTemplateSpecializationType *Spec
= dyn_cast<ClassTemplateSpecializationType>(this))
return Spec->getCanonicalTypeInternal().getDesugaredType();
+ if (const QualifiedNameType *QualName = dyn_cast<QualifiedNameType>(this))
+ return QualName->getNamedType().getDesugaredType();
// FIXME: remove this cast.
return QualType(const_cast<Type*>(this), 0);
@@ -1045,6 +1047,28 @@ ClassTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
Args[Idx].Profile(ID);
}
+QualifiedNameType::QualifiedNameType(const NestedNameSpecifier *Components,
+ unsigned NumComponents,
+ QualType NamedType,
+ QualType CanonType)
+ : Type(QualifiedName, CanonType, NamedType->isDependentType()),
+ NumComponents(NumComponents), NamedType(NamedType) {
+ NestedNameSpecifier *InitComponents
+ = reinterpret_cast<NestedNameSpecifier *>(this + 1);
+ for (unsigned I = 0; I < NumComponents; ++I)
+ new (InitComponents + I) NestedNameSpecifier(Components[I]);
+}
+
+void QualifiedNameType::Profile(llvm::FoldingSetNodeID &ID,
+ const NestedNameSpecifier *Components,
+ unsigned NumComponents,
+ QualType NamedType) {
+ ID.AddInteger(NumComponents);
+ for (unsigned I = 0; I < NumComponents; ++I)
+ ID.AddPointer(Components[I].getAsOpaquePtr());
+ NamedType.Profile(ID);
+}
+
//===----------------------------------------------------------------------===//
// Type Printing
//===----------------------------------------------------------------------===//
@@ -1411,6 +1435,38 @@ getAsStringInternal(std::string &InnerString) const {
InnerString = SpecString + ' ' + InnerString;
}
+void QualifiedNameType::getAsStringInternal(std::string &InnerString) const {
+ std::string MyString;
+
+ for (iterator Comp = begin(), CompEnd = end(); Comp != CompEnd; ++Comp) {
+ if (Type *T = Comp->getAsType()) {
+ std::string TypeStr;
+ if (const TagType *TagT = dyn_cast<TagType>(T))
+ TagT->getAsStringInternal(TypeStr, true);
+ else
+ T->getAsStringInternal(TypeStr);
+
+ MyString += TypeStr;
+ } else if (NamedDecl *NamedDC
+ = dyn_cast_or_null<NamedDecl>(Comp->getAsDeclContext()))
+ MyString += NamedDC->getNameAsString();
+ MyString += "::";
+ }
+
+ std::string TypeStr;
+ if (const TagType *TagT = dyn_cast<TagType>(NamedType.getTypePtr())) {
+ // Suppress printing of 'enum', 'struct', 'union', or 'class'.
+ TagT->getAsStringInternal(TypeStr, true);
+ } else
+ NamedType.getAsStringInternal(TypeStr);
+
+ MyString += TypeStr;
+ if (InnerString.empty())
+ InnerString.swap(MyString);
+ else
+ InnerString = MyString + ' ' + InnerString;
+}
+
void ObjCInterfaceType::getAsStringInternal(std::string &InnerString) const {
if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
InnerString = ' ' + InnerString;
@@ -1451,10 +1507,15 @@ void ObjCQualifiedIdType::getAsStringInternal(std::string &InnerString) const {
}
void TagType::getAsStringInternal(std::string &InnerString) const {
+ getAsStringInternal(InnerString, false);
+}
+
+void TagType::getAsStringInternal(std::string &InnerString,
+ bool SuppressTagKind) const {
if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
InnerString = ' ' + InnerString;
- const char *Kind = getDecl()->getKindName();
+ const char *Kind = SuppressTagKind? 0 : getDecl()->getKindName();
const char *ID;
if (const IdentifierInfo *II = getDecl()->getIdentifier())
ID = II->getName();
diff --git a/clang/lib/AST/TypeSerialization.cpp b/clang/lib/AST/TypeSerialization.cpp
index 8498e0123e6..6f93a1859fe 100644
--- a/clang/lib/AST/TypeSerialization.cpp
+++ b/clang/lib/AST/TypeSerialization.cpp
@@ -418,6 +418,21 @@ CreateImpl(ASTContext& Context, Deserializer& D) {
}
//===----------------------------------------------------------------------===//
+// QualifiedNameType
+//===----------------------------------------------------------------------===//
+void QualifiedNameType::EmitImpl(llvm::Serializer& S) const {
+ S.EmitInt(NumComponents);
+ // FIXME: Serialize the actual components
+ S.Emit(NamedType);
+}
+
+Type*
+QualifiedNameType::CreateImpl(ASTContext& Context, llvm::Deserializer& D) {
+ // FIXME: Implement de-serialization
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
// VariableArrayType
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index b0cf07789b5..cec39fd71a2 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -525,6 +525,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
case Type::BlockPointer:
case Type::MemberPointer:
case Type::ClassTemplateSpecialization:
+ case Type::QualifiedName:
case Type::ObjCQualifiedClass:
// Unsupported types
return llvm::DIType();
diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp
index a498182df71..72ac3112f9d 100644
--- a/clang/lib/Parse/DeclSpec.cpp
+++ b/clang/lib/Parse/DeclSpec.cpp
@@ -15,6 +15,7 @@
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/STLExtras.h"
+#include <cstring>
using namespace clang;
@@ -23,6 +24,66 @@ static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
}
+/// \brief Double the capacity of this scope specifier.
+void CXXScopeSpec::reallocate() {
+ Action::CXXScopeTy **Data = new Action::CXXScopeTy *[Capacity * 2];
+
+ Action::CXXScopeTy **From
+ = Capacity == 4? &InlineScopeReps[0] : ManyScopeReps;
+ std::memcpy(Data, From, Capacity * sizeof(Action::CXXScopeTy *));
+
+ if (Capacity > 4)
+ delete [] ManyScopeReps;
+ ManyScopeReps = Data;
+ Capacity *= 2;
+}
+
+CXXScopeSpec::CXXScopeSpec(const CXXScopeSpec &SS)
+ : Range(SS.Range), NumScopeReps(SS.NumScopeReps), Capacity(SS.Capacity) {
+
+ if (Capacity > 4) {
+ ManyScopeReps = new Action::CXXScopeTy *[Capacity];
+ memcpy(ManyScopeReps, SS.ManyScopeReps,
+ Capacity * sizeof(Action::CXXScopeTy *));
+ } else {
+ memcpy(InlineScopeReps, SS.InlineScopeReps,
+ Capacity * sizeof(Action::CXXScopeTy *));
+ }
+}
+
+CXXScopeSpec &CXXScopeSpec::operator=(const CXXScopeSpec &SS) {
+ // FIXME: Does not provide the strong exception safety guarantee.
+ this->~CXXScopeSpec();
+ new (this) CXXScopeSpec(SS);
+ return *this;
+}
+
+void *CXXScopeSpec::buildAnnotationData() const {
+ uintptr_t *Data = (uintptr_t *)malloc(sizeof(uintptr_t) * (size() + 1));
+ Data[0] = size();
+ for (unsigned I = 0; I < size(); ++I)
+ Data[I + 1] = reinterpret_cast<uintptr_t>(getScopeRep(I));
+ return Data;
+}
+
+void CXXScopeSpec::setFromAnnotationData(void *DataIn) {
+ uintptr_t *Data = static_cast<uintptr_t *>(DataIn);
+ NumScopeReps = *Data;
+
+ // Allocate enough space for the annotation data.
+ if (NumScopeReps > Capacity) {
+ if (Capacity > 4)
+ delete [] ManyScopeReps;
+
+ Capacity = NumScopeReps;
+ ManyScopeReps = new Action::CXXScopeTy *[Capacity];
+ }
+
+ if (Capacity > 4)
+ std::memcpy(ManyScopeReps, Data + 1, sizeof(uintptr_t) * NumScopeReps);
+ else
+ std::memcpy(InlineScopeReps, Data + 1, sizeof(uintptr_t) * NumScopeReps);
+}
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
/// "TheDeclarator" is the declarator that this will be added to.
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 25565e65768..0dddfdff794 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -491,7 +491,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
goto DoneWithDeclSpec;
CXXScopeSpec SS;
- SS.setScopeRep(Tok.getAnnotationValue());
+ SS.setFromAnnotationData(Tok.getAnnotationValue());
SS.setRange(Tok.getAnnotationRange());
// If the next token is the name of the class type that the C++ scope
@@ -508,7 +508,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
if (TypeRep == 0)
goto DoneWithDeclSpec;
-
+
+ CXXScopeSpec::freeAnnotationData(Tok.getAnnotationValue());
ConsumeToken(); // The C++ scope.
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index e1b5db9c440..731f4c7957f 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -36,7 +36,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
"Call sites of this function should be guarded by checking for C++");
if (Tok.is(tok::annot_cxxscope)) {
- SS.setScopeRep(Tok.getAnnotationValue());
+ SS.setFromAnnotationData(Tok.getAnnotationValue());
+ CXXScopeSpec::freeAnnotationData(Tok.getAnnotationValue());
SS.setRange(Tok.getAnnotationRange());
ConsumeToken();
return true;
@@ -53,7 +54,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
// '::' - Global scope qualifier.
SourceLocation CCLoc = ConsumeToken();
SS.setBeginLoc(CCLoc);
- SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
+ SS.addScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
SS.setEndLoc(CCLoc);
HasScopeSpecifier = true;
}
@@ -79,7 +80,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
if (SS.isInvalid())
continue;
- SS.setScopeRep(
+ SS.addScopeRep(
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II));
SS.setEndLoc(CCLoc);
continue;
@@ -149,7 +150,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
if (TemplateId->Kind == TNK_Class_template) {
if (AnnotateTemplateIdTokenAsType(&SS))
- SS.setScopeRep(0);
+ SS.clear();
assert(Tok.is(tok::annot_typename) &&
"AnnotateTemplateIdTokenAsType isn't working");
@@ -164,7 +165,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
HasScopeSpecifier = true;
}
- SS.setScopeRep(
+ SS.addScopeRep(
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
TypeToken.getAnnotationValue(),
TypeToken.getAnnotationRange(),
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 5666051fe59..8c3ff443f15 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -856,7 +856,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() {
else
PP.EnterToken(Tok);
Tok.setKind(tok::annot_cxxscope);
- Tok.setAnnotationValue(SS.getScopeRep());
+ Tok.setAnnotationValue(SS.buildAnnotationData());
Tok.setAnnotationRange(SS.getRange());
// In case the tokens were cached, have Preprocessor replace them with the
@@ -888,7 +888,7 @@ bool Parser::TryAnnotateCXXScopeToken() {
else
PP.EnterToken(Tok);
Tok.setKind(tok::annot_cxxscope);
- Tok.setAnnotationValue(SS.getScopeRep());
+ Tok.setAnnotationValue(SS.buildAnnotationData());
Tok.setAnnotationRange(SS.getRange());
// In case the tokens were cached, have Preprocessor replace them with the
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index d84829a0c7c..5106a54f952 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -1451,21 +1451,8 @@ public:
SourceLocation RParen);
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);
+
+ DeclContext *computeDeclContext(const CXXScopeSpec &SS);
/// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
/// global scope ('::').
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index e30ec2adcf2..156f3a12fbb 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -13,51 +13,20 @@
#include "Sema.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Parse/DeclSpec.h"
#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())
+/// \brief Compute the DeclContext that is associated with the given
+/// scope specifier.
+DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS) {
+ if (!SS.isSet() || SS.isInvalid())
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;
+ NestedNameSpecifier NNS
+ = NestedNameSpecifier::getFromOpaquePtr(SS.getCurrentScopeRep());
+ return NNS.computeDeclContext(Context);
}
/// \brief Require that the context specified by SS be complete.
@@ -73,7 +42,7 @@ bool Sema::RequireCompleteDeclContext(const CXXScopeSpec &SS) {
if (!SS.isSet() || SS.isInvalid())
return false;
- DeclContext *DC = getScopeRepAsDeclContext(SS);
+ DeclContext *DC = computeDeclContext(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.
@@ -95,7 +64,7 @@ bool Sema::RequireCompleteDeclContext(const CXXScopeSpec &SS) {
/// global scope ('::').
Sema::CXXScopeTy *Sema::ActOnCXXGlobalScopeSpecifier(Scope *S,
SourceLocation CCLoc) {
- return createScopeRep(Context.getTranslationUnitDecl());
+ return NestedNameSpecifier(Context.getTranslationUnitDecl()).getAsOpaquePtr();
}
/// ActOnCXXNestedNameSpecifier - Called during parsing of a
@@ -114,9 +83,10 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
if (SD) {
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
if (TD->getUnderlyingType()->isRecordType())
- return createScopeRep(Context.getTypeDeclType(TD));
+ return NestedNameSpecifier(Context.getTypeDeclType(TD).getTypePtr())
+ .getAsOpaquePtr();
} else if (isa<NamespaceDecl>(SD) || isa<RecordDecl>(SD)) {
- return createScopeRep(cast<DeclContext>(SD));
+ return NestedNameSpecifier(cast<DeclContext>(SD)).getAsOpaquePtr();
}
// FIXME: Template parameters and dependent types.
@@ -152,7 +122,8 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
TypeTy *Ty,
SourceRange TypeRange,
SourceLocation CCLoc) {
- return createScopeRep(QualType::getFromOpaquePtr(Ty));
+ return NestedNameSpecifier(QualType::getFromOpaquePtr(Ty).getTypePtr())
+ .getAsOpaquePtr();
}
/// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
@@ -165,7 +136,7 @@ void Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
assert(PreDeclaratorDC == 0 && "Previous declarator context not popped?");
PreDeclaratorDC = static_cast<DeclContext*>(S->getEntity());
- CurContext = getScopeRepAsDeclContext(SS);
+ CurContext = computeDeclContext(SS);
S->setEntity(CurContext);
}
@@ -176,8 +147,7 @@ void Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
/// defining scope.
void Sema::ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
- assert(S->getEntity() == getScopeRepAsDeclContext(SS) &&
- "Context imbalance!");
+ assert(S->getEntity() == computeDeclContext(SS) && "Context imbalance!");
S->setEntity(PreDeclaratorDC);
PreDeclaratorDC = 0;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c3dfd19be4b..63d446f70c0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -72,22 +72,32 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
}
if (IIDecl) {
+ QualType T;
+
if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
// Check whether we can use this type
(void)DiagnoseUseOfDecl(IIDecl, NameLoc);
- return Context.getTypeDeclType(TD).getAsOpaquePtr();
- }
-
- if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
+ T = Context.getTypeDeclType(TD);
+ } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
// Check whether we can use this interface.
(void)DiagnoseUseOfDecl(IIDecl, NameLoc);
- return Context.getObjCInterfaceType(IDecl).getAsOpaquePtr();
+ T = Context.getObjCInterfaceType(IDecl);
+ } else
+ return 0;
+
+ if (SS && SS->isNotEmpty() && SS->isSet()) {
+ llvm::SmallVector<NestedNameSpecifier, 4> TNNs;
+ for (CXXScopeSpec::iterator TNN = SS->begin(), TNNEnd = SS->end();
+ TNN != TNNEnd; ++TNN)
+ TNNs.push_back(NestedNameSpecifier::getFromOpaquePtr(*TNN));
+ T = Context.getQualifiedNameType(&TNNs[0], TNNs.size(), T);
}
- // Otherwise, could be a variable, function etc.
+ return T.getAsOpaquePtr();
}
+
return 0;
}
@@ -1257,7 +1267,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
DeclSpec::SCS_static,
D.getIdentifierLoc());
} else { // Something like "int foo::x;"
- DC = getScopeRepAsDeclContext(D.getCXXScopeSpec());
+ DC = computeDeclContext(D.getCXXScopeSpec());
// FIXME: RequireCompleteDeclContext(D.getCXXScopeSpec()); ?
PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true);
@@ -3020,7 +3030,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
}
// FIXME: RequireCompleteDeclContext(SS)?
- DC = getScopeRepAsDeclContext(SS);
+ DC = computeDeclContext(SS);
SearchDC = DC;
// Look-up name inside 'foo::'.
PrevDecl = dyn_cast_or_null<TagDecl>(
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 3307dd0cc45..10e7bd4c973 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -299,8 +299,8 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
bool Sema::isCurrentClassName(const IdentifierInfo &II, Scope *,
const CXXScopeSpec *SS) {
CXXRecordDecl *CurDecl;
- if (SS) {
- DeclContext *DC = getScopeRepAsDeclContext(*SS);
+ if (SS && SS->isSet() && !SS->isInvalid()) {
+ DeclContext *DC = computeDeclContext(*SS);
CurDecl = dyn_cast_or_null<CXXRecordDecl>(DC);
} else
CurDecl = dyn_cast_or_null<CXXRecordDecl>(CurContext);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 1e184d0349b..cec94cfdf06 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -727,7 +727,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// 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 = getScopeRepAsDeclContext(*SS);
+ DeclContext *DC = computeDeclContext(*SS);
if (D && isa<CXXRecordDecl>(DC)) {
QualType DType;
if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
@@ -942,7 +942,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// - a nested-name-specifier that contains a class-name that
// names a dependent type.
else if (SS && !SS->isEmpty()) {
- for (DeclContext *DC = getScopeRepAsDeclContext(*SS);
+ for (DeclContext *DC = computeDeclContext(*SS);
DC; DC = DC->getParent()) {
// FIXME: could stop early at namespace scope.
if (DC->isRecord()) {
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index d6c36d44a9d..616ee3dd932 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1038,9 +1038,10 @@ Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS,
if (SS->isInvalid() || RequireCompleteDeclContext(*SS))
return LookupResult::CreateLookupResult(Context, 0);
- if (SS->isSet())
- return LookupQualifiedName(getScopeRepAsDeclContext(*SS),
+ if (SS->isSet()) {
+ return LookupQualifiedName(computeDeclContext(*SS),
Name, NameKind, RedeclarationOnly);
+ }
}
return LookupName(S, Name, NameKind, RedeclarationOnly,
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 6277d9e5122..f5317787bac 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -399,7 +399,7 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
DeclContext *SemanticContext = CurContext;
if (SS.isNotEmpty() && !SS.isInvalid()) {
- SemanticContext = getScopeRepAsDeclContext(SS);
+ SemanticContext = computeDeclContext(SS);
// FIXME: need to match up several levels of template parameter
// lists here.
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 4341fc94f90..7df9941aa5b 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -492,6 +492,14 @@ InstantiateClassTemplateSpecializationType(
QualType
TemplateTypeInstantiator::
+InstantiateQualifiedNameType(const QualifiedNameType *T,
+ unsigned Quals) const {
+ assert(false && "Cannot have dependent qualified name types (yet)");
+ return QualType();
+}
+
+QualType
+TemplateTypeInstantiator::
InstantiateObjCInterfaceType(const ObjCInterfaceType *T,
unsigned Quals) const {
assert(false && "Objective-C types cannot be dependent");
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index c52f64055b8..a8be924fc88 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -742,7 +742,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
}
case DeclaratorChunk::MemberPointer:
// The scope spec must refer to a class, or be dependent.
- DeclContext *DC = getScopeRepAsDeclContext(DeclType.Mem.Scope());
+ DeclContext *DC = computeDeclContext(DeclType.Mem.Scope());
QualType ClsType;
// FIXME: Extend for dependent types when it's actually supported.
// See ActOnCXXNestedNameSpecifier.
@@ -810,8 +810,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
((D.getContext() != Declarator::MemberContext &&
(!D.getCXXScopeSpec().isSet() ||
- !static_cast<DeclContext*>(D.getCXXScopeSpec().getScopeRep())
- ->isRecord())) ||
+ !computeDeclContext(D.getCXXScopeSpec())->isRecord())) ||
D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)) {
if (D.isFunctionDeclarator())
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_function_type);
OpenPOWER on IntegriCloud