Semantic analysis, ASTs, and unqualified name lookup support for C++
using directives, from Piotr Rak!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63646 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index b0a0a5e..0969cd0 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -539,10 +539,6 @@
void CheckCXXDefaultArguments(FunctionDecl *FD);
void CheckExtraCXXDefaultArguments(Declarator &D);
- // FIXME: NamespaceNameOnly parameter is added temporarily
- // we will need a better way to specify lookup criteria for things
- // like template specializations, explicit template instantiations, etc.
-
Scope *getNonFieldDeclScope(Scope *S);
/// \name Name lookup
@@ -614,6 +610,9 @@
/// First is a single declaration (a Decl*), which may be NULL.
SingleDecl,
+ /// First is a single declaration (an OverloadedFunctionDecl*).
+ OverloadedDeclSingleDecl,
+
/// [First, Last) is an iterator range represented as opaque
/// pointers used to reconstruct IdentifierResolver::iterators.
OverloadedDeclFromIdResolver,
@@ -626,7 +625,13 @@
/// by the LookupResult. Last is non-zero to indicate that the
/// ambiguity is caused by two names found in base class
/// subobjects of different types.
- AmbiguousLookup
+ AmbiguousLookupStoresBasePaths,
+
+ /// [First, Last) is an iterator range represented as opaque
+ /// pointers used to reconstruct new'ed Decl*[] array containing
+ /// found ambiguous decls. LookupResult is owner of this array.
+ AmbiguousLookupStoresDecls
+
} StoredKind;
/// The first lookup result, whose contents depend on the kind of
@@ -635,14 +640,14 @@
/// IdentifierResolver::iterator (if StoredKind ==
/// OverloadedDeclFromIdResolver), a DeclContext::lookup_iterator
/// (if StoredKind == OverloadedDeclFromDeclContext), or a
- /// BasePaths pointer (if StoredKind == AmbiguousLookup).
+ /// BasePaths pointer (if StoredKind == AmbiguousLookupStoresBasePaths).
mutable uintptr_t First;
/// The last lookup result, whose contents depend on the kind of
/// lookup result. This may be unused (if StoredKind ==
/// SingleDecl), it may have the same type as First (for
/// overloaded function declarations), or is may be used as a
- /// Boolean value (if StoredKind == AmbiguousLookup).
+ /// Boolean value (if StoredKind == AmbiguousLookupStoresBasePaths).
mutable uintptr_t Last;
/// Context - The context in which we will build any
@@ -690,17 +695,25 @@
/// return d.x; // error: 'x' is found in two A subobjects (of B and C)
/// }
/// @endcode
- AmbiguousBaseSubobjects
+ AmbiguousBaseSubobjects,
+
+ /// Name lookup results in an ambiguity because multiple definitions
+ /// of entity that meet the lookup criteria were found in different
+ /// declaration contexts.
+ /// @code
+ /// namespace A {
+ /// int i;
+ /// namespace B { int i; }
+ /// int test() {
+ /// using namespace B;
+ /// return i; // error 'i' is found in namespace A and A::B
+ /// }
+ /// }
+ /// @endcode
+ AmbiguousReference
};
- static LookupResult CreateLookupResult(ASTContext &Context, Decl *D) {
- LookupResult Result;
- Result.StoredKind = SingleDecl;
- Result.First = reinterpret_cast<uintptr_t>(D);
- Result.Last = 0;
- Result.Context = &Context;
- return Result;
- }
+ static LookupResult CreateLookupResult(ASTContext &Context, Decl *D);
static LookupResult CreateLookupResult(ASTContext &Context,
IdentifierResolver::iterator F,
@@ -713,20 +726,37 @@
static LookupResult CreateLookupResult(ASTContext &Context, BasePaths *Paths,
bool DifferentSubobjectTypes) {
LookupResult Result;
- Result.StoredKind = AmbiguousLookup;
+ Result.StoredKind = AmbiguousLookupStoresBasePaths;
Result.First = reinterpret_cast<uintptr_t>(Paths);
Result.Last = DifferentSubobjectTypes? 1 : 0;
Result.Context = &Context;
return Result;
}
+ template <typename Iterator>
+ static LookupResult CreateLookupResult(ASTContext &Context,
+ Iterator B, std::size_t Len) {
+ Decl ** Array = new Decl*[Len];
+ for (std::size_t Idx = 0; Idx < Len; ++Idx, ++B)
+ Array[Idx] = *B;
+ LookupResult Result;
+ Result.StoredKind = AmbiguousLookupStoresDecls;
+ Result.First = reinterpret_cast<uintptr_t>(Array);
+ Result.Last = reinterpret_cast<uintptr_t>(Array + Len);
+ Result.Context = &Context;
+ return Result;
+ }
+
LookupKind getKind() const;
/// @brief Determine whether name look found something.
operator bool() const { return getKind() != NotFound; }
/// @brief Determines whether the lookup resulted in an ambiguity.
- bool isAmbiguous() const { return StoredKind == AmbiguousLookup; }
+ bool isAmbiguous() const {
+ return StoredKind == AmbiguousLookupStoresBasePaths ||
+ StoredKind == AmbiguousLookupStoresDecls;
+ }
/// @brief Allows conversion of a lookup result into a
/// declaration, with the same behavior as getAsDecl.
@@ -786,6 +816,14 @@
iterator end();
};
+private:
+ typedef llvm::SmallVector<LookupResult, 3> LookupResultsVecTy;
+
+ std::pair<bool, LookupResult> CppLookupName(Scope *S, DeclarationName Name,
+ LookupNameKind NameKind,
+ bool RedeclarationOnly);
+
+public:
/// Determines whether D is a suitable lookup result according to the
/// lookup criteria.
bool isAcceptableLookupResult(Decl *D, LookupNameKind NameKind,
@@ -1171,6 +1209,8 @@
IdentifierInfo *NamespcName,
AttributeList *AttrList);
+ void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
+
/// AddCXXDirectInitializerToDecl - This action is called immediately after
/// ActOnDeclarator, when a C++ direct initializer is present.
/// e.g: "int x(1);"