diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 23 | ||||
-rw-r--r-- | clang/lib/AST/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/AST/NestedNameSpecifier.cpp | 34 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 63 | ||||
-rw-r--r-- | clang/lib/AST/TypeSerialization.cpp | 15 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Parse/DeclSpec.cpp | 61 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 17 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCXXScopeSpec.cpp | 64 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 26 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 5 |
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); |