aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/DeclBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/DeclBase.cpp')
-rw-r--r--lib/AST/DeclBase.cpp141
1 files changed, 76 insertions, 65 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index b2806f092cbd..321e40b43899 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -43,7 +43,7 @@ static bool StatSwitch = false;
const char *Decl::getDeclKindName() const {
switch (DeclKind) {
- default: assert(0 && "Declaration not in DeclNodes.inc!");
+ default: llvm_unreachable("Declaration not in DeclNodes.inc!");
#define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
@@ -62,7 +62,7 @@ void Decl::setInvalidDecl(bool Invalid) {
const char *DeclContext::getDeclKindName() const {
switch (DeclKind) {
- default: assert(0 && "Declaration context not in DeclNodes.inc!");
+ default: llvm_unreachable("Declaration context not in DeclNodes.inc!");
#define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
@@ -100,7 +100,7 @@ void Decl::PrintStats() {
void Decl::add(Kind k) {
switch (k) {
- default: assert(0 && "Declaration not in DeclNodes.inc!");
+ default: llvm_unreachable("Declaration not in DeclNodes.inc!");
#define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
@@ -133,14 +133,18 @@ bool Decl::isFunctionOrFunctionTemplate() const {
return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
}
-bool Decl::isDefinedOutsideFunctionOrMethod() const {
- for (const DeclContext *DC = getDeclContext();
- DC && !DC->isTranslationUnit();
+bool Decl::isTemplateDecl() const {
+ return isa<TemplateDecl>(this);
+}
+
+const DeclContext *Decl::getParentFunctionOrMethod() const {
+ for (const DeclContext *DC = getDeclContext();
+ DC && !DC->isTranslationUnit() && !DC->isNamespace();
DC = DC->getParent())
if (DC->isFunctionOrMethod())
- return false;
+ return DC;
- return true;
+ return 0;
}
@@ -148,7 +152,7 @@ bool Decl::isDefinedOutsideFunctionOrMethod() const {
// PrettyStackTraceDecl Implementation
//===----------------------------------------------------------------------===//
-void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
+void PrettyStackTraceDecl::print(raw_ostream &OS) const {
SourceLocation TheLoc = Loc;
if (TheLoc.isInvalid() && TheDecl)
TheLoc = TheDecl->getLocation();
@@ -265,13 +269,13 @@ bool Decl::isReferenced() const {
static AvailabilityResult CheckAvailability(ASTContext &Context,
const AvailabilityAttr *A,
std::string *Message) {
- llvm::StringRef TargetPlatform = Context.Target.getPlatformName();
- llvm::StringRef PrettyPlatformName
+ StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
+ StringRef PrettyPlatformName
= AvailabilityAttr::getPrettyPlatformName(TargetPlatform);
if (PrettyPlatformName.empty())
PrettyPlatformName = TargetPlatform;
- VersionTuple TargetMinVersion = Context.Target.getPlatformMinVersion();
+ VersionTuple TargetMinVersion = Context.getTargetInfo().getPlatformMinVersion();
if (TargetMinVersion.empty())
return AR_Available;
@@ -493,6 +497,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case UsingDirective:
case ClassTemplateSpecialization:
case ClassTemplatePartialSpecialization:
+ case ClassScopeFunctionSpecialization:
case ObjCImplementation:
case ObjCCategory:
case ObjCCategoryImpl:
@@ -566,8 +571,7 @@ Decl *Decl::castFromDeclContext (const DeclContext *D) {
if (DK >= first##NAME && DK <= last##NAME) \
return static_cast<NAME##Decl*>(const_cast<DeclContext*>(D));
#include "clang/AST/DeclNodes.inc"
- assert(false && "a decl that inherits DeclContext isn't handled");
- return 0;
+ llvm_unreachable("a decl that inherits DeclContext isn't handled");
}
}
@@ -586,8 +590,7 @@ DeclContext *Decl::castToDeclContext(const Decl *D) {
if (DK >= first##NAME && DK <= last##NAME) \
return static_cast<NAME##Decl*>(const_cast<Decl*>(D));
#include "clang/AST/DeclNodes.inc"
- assert(false && "a decl that inherits DeclContext isn't handled");
- return 0;
+ llvm_unreachable("a decl that inherits DeclContext isn't handled");
}
}
@@ -627,7 +630,8 @@ void Decl::CheckAccessDeclContext() const {
isa<ParmVarDecl>(this) ||
// FIXME: a ClassTemplateSpecialization or CXXRecordDecl can have
// AS_none as access specifier.
- isa<CXXRecordDecl>(this))
+ isa<CXXRecordDecl>(this) ||
+ isa<ClassScopeFunctionSpecializationDecl>(this))
return;
assert(Access != AS_none &&
@@ -812,11 +816,15 @@ DeclContext *DeclContext::getNextContext() {
}
std::pair<Decl *, Decl *>
-DeclContext::BuildDeclChain(const llvm::SmallVectorImpl<Decl*> &Decls) {
+DeclContext::BuildDeclChain(const SmallVectorImpl<Decl*> &Decls,
+ bool FieldsAlreadyLoaded) {
// Build up a chain of declarations via the Decl::NextDeclInContext field.
Decl *FirstNewDecl = 0;
Decl *PrevDecl = 0;
for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
+ if (FieldsAlreadyLoaded && isa<FieldDecl>(Decls[I]))
+ continue;
+
Decl *D = Decls[I];
if (PrevDecl)
PrevDecl->NextDeclInContext = D;
@@ -838,9 +846,9 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const {
// Notify that we have a DeclContext that is initializing.
ExternalASTSource::Deserializing ADeclContext(Source);
-
+
// Load the external declarations, if any.
- llvm::SmallVector<Decl*, 64> Decls;
+ SmallVector<Decl*, 64> Decls;
ExternalLexicalStorage = false;
switch (Source->FindExternalLexicalDecls(this, Decls)) {
case ELR_Success:
@@ -855,17 +863,16 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const {
return;
// We may have already loaded just the fields of this record, in which case
- // don't add the decls, just replace the FirstDecl/LastDecl chain.
+ // we need to ignore them.
+ bool FieldsAlreadyLoaded = false;
if (const RecordDecl *RD = dyn_cast<RecordDecl>(this))
- if (RD->LoadedFieldsFromExternalStorage) {
- llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls);
- return;
- }
-
+ FieldsAlreadyLoaded = RD->LoadedFieldsFromExternalStorage;
+
// Splice the newly-read declarations into the beginning of the list
// of declarations.
Decl *ExternalFirst, *ExternalLast;
- llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls);
+ llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls,
+ FieldsAlreadyLoaded);
ExternalLast->NextDeclInContext = FirstDecl;
FirstDecl = ExternalFirst;
if (!LastDecl)
@@ -890,7 +897,7 @@ ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,
DeclContext::lookup_result
ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
DeclarationName Name,
- llvm::SmallVectorImpl<NamedDecl*> &Decls) {
+ ArrayRef<NamedDecl*> Decls) {
ASTContext &Context = DC->getParentASTContext();;
StoredDeclsMap *Map;
@@ -898,35 +905,17 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
Map = DC->CreateStoredDeclsMap(Context);
StoredDeclsList &List = (*Map)[Name];
- for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
+ for (ArrayRef<NamedDecl*>::iterator
+ I = Decls.begin(), E = Decls.end(); I != E; ++I) {
if (List.isNull())
- List.setOnlyValue(Decls[I]);
+ List.setOnlyValue(*I);
else
- List.AddSubsequentDecl(Decls[I]);
+ List.AddSubsequentDecl(*I);
}
return List.getLookupResult();
}
-void ExternalASTSource::MaterializeVisibleDeclsForName(const DeclContext *DC,
- DeclarationName Name,
- llvm::SmallVectorImpl<NamedDecl*> &Decls) {
- assert(DC->LookupPtr);
- StoredDeclsMap &Map = *DC->LookupPtr;
-
- // If there's an entry in the table the visible decls for this name have
- // already been deserialized.
- if (Map.find(Name) == Map.end()) {
- StoredDeclsList &List = Map[Name];
- for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
- if (List.isNull())
- List.setOnlyValue(Decls[I]);
- else
- List.AddSubsequentDecl(Decls[I]);
- }
- }
-}
-
DeclContext::decl_iterator DeclContext::noload_decls_begin() const {
return decl_iterator(FirstDecl);
}
@@ -939,8 +928,6 @@ DeclContext::decl_iterator DeclContext::decls_begin() const {
if (hasExternalLexicalStorage())
LoadLexicalDeclsFromExternalStorage();
- // FIXME: Check whether we need to load some declarations from
- // external storage.
return decl_iterator(FirstDecl);
}
@@ -988,6 +975,9 @@ void DeclContext::removeDecl(Decl *D) {
if (isa<NamedDecl>(D)) {
NamedDecl *ND = cast<NamedDecl>(D);
+ // Remove only decls that have a name
+ if (!ND->getDeclName()) return;
+
StoredDeclsMap *Map = getPrimaryContext()->LookupPtr;
if (!Map) return;
@@ -1038,12 +1028,10 @@ void DeclContext::buildLookup(DeclContext *DCtx) {
if (D->getDeclContext() == DCtx)
makeDeclVisibleInContextImpl(ND);
- // Insert any forward-declared Objective-C interfaces into the lookup
+ // Insert any forward-declared Objective-C interface into the lookup
// data structure.
if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D))
- for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end();
- I != IEnd; ++I)
- makeDeclVisibleInContextImpl(I->getInterface());
+ makeDeclVisibleInContextImpl(Class->getForwardInterfaceDecl());
// If this declaration is itself a transparent declaration context or
// inline namespace, add its members (recursively).
@@ -1093,6 +1081,38 @@ DeclContext::lookup(DeclarationName Name) const {
return const_cast<DeclContext*>(this)->lookup(Name);
}
+void DeclContext::localUncachedLookup(DeclarationName Name,
+ llvm::SmallVectorImpl<NamedDecl *> &Results) {
+ Results.clear();
+
+ // If there's no external storage, just perform a normal lookup and copy
+ // the results.
+ if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage()) {
+ lookup_result LookupResults = lookup(Name);
+ Results.insert(Results.end(), LookupResults.first, LookupResults.second);
+ return;
+ }
+
+ // If we have a lookup table, check there first. Maybe we'll get lucky.
+ if (LookupPtr) {
+ StoredDeclsMap::iterator Pos = LookupPtr->find(Name);
+ if (Pos != LookupPtr->end()) {
+ Results.insert(Results.end(),
+ Pos->second.getLookupResult().first,
+ Pos->second.getLookupResult().second);
+ return;
+ }
+ }
+
+ // Slow case: grovel through the declarations in our chain looking for
+ // matches.
+ for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) {
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+ if (ND->getDeclName() == Name)
+ Results.push_back(ND);
+ }
+}
+
DeclContext *DeclContext::getRedeclContext() {
DeclContext *Ctx = this;
// Skip through transparent contexts.
@@ -1205,15 +1225,6 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
DeclNameEntries.AddSubsequentDecl(D);
}
-void DeclContext::MaterializeVisibleDeclsFromExternalStorage() {
- ExternalASTSource *Source = getParentASTContext().getExternalSource();
- assert(hasExternalVisibleStorage() && Source && "No external storage?");
-
- if (!LookupPtr)
- CreateStoredDeclsMap(getParentASTContext());
- Source->MaterializeVisibleDecls(this);
-}
-
/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
/// this context.
DeclContext::udir_iterator_range