[cfe-commits] r105882 - in /cfe/trunk: include/clang/AST/Decl.h lib/AST/Decl.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp
Abramo Bagnara
abramo.bagnara at gmail.com
Sat Jun 12 01:15:14 PDT 2010
Author: abramo
Date: Sat Jun 12 03:15:14 2010
New Revision: 105882
URL: http://llvm.org/viewvc/llvm-project?rev=105882&view=rev
Log:
Added template parameters info for out-of-line definitions of class template methods.
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=105882&r1=105881&r2=105882&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Jun 12 03:15:14 2010
@@ -28,6 +28,8 @@
class Stmt;
class CompoundStmt;
class StringLiteral;
+class NestedNameSpecifier;
+class TemplateParameterList;
class TemplateArgumentList;
class MemberSpecializationInfo;
class FunctionTemplateSpecializationInfo;
@@ -364,15 +366,42 @@
static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
};
+/// QualifierInfo - A struct with extended info about a syntactic
+/// name qualifier, to be used for the case of out-of-line declarations.
+struct QualifierInfo {
+ /// NNS - The syntactic name qualifier.
+ NestedNameSpecifier *NNS;
+ /// NNSRange - The source range for the qualifier.
+ SourceRange NNSRange;
+ /// NumTemplParamLists - The number of template parameter lists
+ /// that were matched against the template-ids occurring into the NNS.
+ unsigned NumTemplParamLists;
+ /// TemplParamLists - A new-allocated array of size NumTemplParamLists,
+ /// containing pointers to the matched template parameter lists.
+ TemplateParameterList** TemplParamLists;
+
+ /// Default constructor.
+ QualifierInfo()
+ : NNS(0), NNSRange(), NumTemplParamLists(0), TemplParamLists(0) {}
+ /// setTemplateParameterListsInfo - Sets info about matched template
+ /// parameter lists.
+ void setTemplateParameterListsInfo(unsigned NumTPLists,
+ TemplateParameterList **TPLists);
+ /// Destructor: frees the array of template parameter lists pointers.
+ ~QualifierInfo() { delete[] TemplParamLists; }
+private:
+ // Copy constructor and copy assignment are disabled.
+ QualifierInfo(const QualifierInfo&);
+ QualifierInfo& operator=(const QualifierInfo&);
+};
+
/// \brief Represents a ValueDecl that came out of a declarator.
/// Contains type source information through TypeSourceInfo.
class DeclaratorDecl : public ValueDecl {
// A struct representing both a TInfo and a syntactic qualifier,
// to be used for the (uncommon) case of out-of-line declarations.
- struct ExtInfo {
+ struct ExtInfo : public QualifierInfo {
TypeSourceInfo *TInfo;
- NestedNameSpecifier *NNS;
- SourceRange NNSRange;
};
llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
@@ -392,25 +421,37 @@
TypeSourceInfo *getTypeSourceInfo() const {
return hasExtInfo()
- ? DeclInfo.get<ExtInfo*>()->TInfo
+ ? getExtInfo()->TInfo
: DeclInfo.get<TypeSourceInfo*>();
}
void setTypeSourceInfo(TypeSourceInfo *TI) {
if (hasExtInfo())
- DeclInfo.get<ExtInfo*>()->TInfo = TI;
+ getExtInfo()->TInfo = TI;
else
DeclInfo = TI;
}
NestedNameSpecifier *getQualifier() const {
- return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNS : 0;
+ return hasExtInfo() ? getExtInfo()->NNS : 0;
}
SourceRange getQualifierRange() const {
- return hasExtInfo() ? DeclInfo.get<ExtInfo*>()->NNSRange : SourceRange();
+ return hasExtInfo() ? getExtInfo()->NNSRange : SourceRange();
}
void setQualifierInfo(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange);
+ unsigned getNumTemplateParameterLists() const {
+ return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
+ }
+ TemplateParameterList *getTemplateParameterList(unsigned index) const {
+ assert(index < getNumTemplateParameterLists());
+ return getExtInfo()->TemplParamLists[index];
+ }
+ void setTemplateParameterListsInfo(unsigned NumTPLists,
+ TemplateParameterList **TPLists) {
+ getExtInfo()->setTemplateParameterListsInfo(NumTPLists, TPLists);
+ }
+
SourceLocation getTypeSpecStartLoc() const;
// Implement isa/cast/dyncast/etc.
@@ -1715,10 +1756,7 @@
// A struct representing syntactic qualifier info,
// to be used for the (uncommon) case of out-of-line declarations.
- struct ExtInfo {
- NestedNameSpecifier *NNS;
- SourceRange NNSRange;
- };
+ typedef QualifierInfo ExtInfo;
/// TypedefDeclOrQualifier - If the (out-of-line) tag declaration name
/// is qualified, it points to the qualifier info (nns and range);
@@ -1830,20 +1868,30 @@
TypedefDecl *getTypedefForAnonDecl() const {
return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
}
-
+
void setTypedefForAnonDecl(TypedefDecl *TDD);
-
+
NestedNameSpecifier *getQualifier() const {
- return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNS : 0;
+ return hasExtInfo() ? getExtInfo()->NNS : 0;
}
SourceRange getQualifierRange() const {
- return hasExtInfo()
- ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNSRange
- : SourceRange();
+ return hasExtInfo() ? getExtInfo()->NNSRange : SourceRange();
}
void setQualifierInfo(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange);
+ unsigned getNumTemplateParameterLists() const {
+ return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
+ }
+ TemplateParameterList *getTemplateParameterList(unsigned i) const {
+ assert(i < getNumTemplateParameterLists());
+ return getExtInfo()->TemplParamLists[i];
+ }
+ void setTemplateParameterListsInfo(unsigned NumTPLists,
+ TemplateParameterList **TPLists) {
+ getExtInfo()->setTemplateParameterListsInfo(NumTPLists, TPLists);
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TagDecl *D) { return true; }
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=105882&r1=105881&r2=105882&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sat Jun 12 03:15:14 2010
@@ -566,6 +566,29 @@
}
}
+void
+QualifierInfo::setTemplateParameterListsInfo(unsigned NumTPLists,
+ TemplateParameterList **TPLists) {
+ assert((NumTPLists == 0 || TPLists != 0) &&
+ "Empty array of template parameters with positive size!");
+ assert((NumTPLists == 0 || NNS) &&
+ "Nonempty array of template parameters with no qualifier!");
+
+ // Free previous template parameters (if any).
+ if (NumTemplParamLists > 0) {
+ delete[] TemplParamLists;
+ TemplParamLists = 0;
+ NumTemplParamLists = 0;
+ }
+ // Set info on matched template parameter lists (if any).
+ if (NumTPLists > 0) {
+ TemplParamLists = new TemplateParameterList*[NumTPLists];
+ NumTemplParamLists = NumTPLists;
+ for (unsigned i = NumTPLists; i-- > 0; )
+ TemplParamLists[i] = TPLists[i];
+ }
+}
+
//===----------------------------------------------------------------------===//
// VarDecl Implementation
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=105882&r1=105881&r2=105882&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Jun 12 03:15:14 2010
@@ -2532,6 +2532,7 @@
// Match up the template parameter lists with the scope specifier, then
// determine whether we have a template or a template specialization.
bool isExplicitSpecialization = false;
+ unsigned NumMatchedTemplateParamLists = TemplateParamLists.size();
if (TemplateParameterList *TemplateParams
= MatchTemplateParametersToScopeSpecifier(
D.getDeclSpec().getSourceRange().getBegin(),
@@ -2540,6 +2541,9 @@
TemplateParamLists.size(),
/*never a friend*/ false,
isExplicitSpecialization)) {
+ // All but one template parameter lists have been matching.
+ --NumMatchedTemplateParamLists;
+
if (TemplateParams->size() > 0) {
// There is no such thing as a variable template.
Diag(D.getIdentifierLoc(), diag::err_template_variable)
@@ -2568,6 +2572,11 @@
SetNestedNameSpecifier(NewVD, D);
+ if (NumMatchedTemplateParamLists > 0) {
+ NewVD->setTemplateParameterListsInfo(NumMatchedTemplateParamLists,
+ (TemplateParameterList**)TemplateParamLists.release());
+ }
+
if (D.getDeclSpec().isThreadSpecified()) {
if (NewVD->hasLocalStorage())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_non_global);
@@ -3088,6 +3097,7 @@
FunctionTemplateDecl *FunctionTemplate = 0;
bool isExplicitSpecialization = false;
bool isFunctionTemplateSpecialization = false;
+ unsigned NumMatchedTemplateParamLists = TemplateParamLists.size();
if (TemplateParameterList *TemplateParams
= MatchTemplateParametersToScopeSpecifier(
D.getDeclSpec().getSourceRange().getBegin(),
@@ -3096,6 +3106,9 @@
TemplateParamLists.size(),
isFriend,
isExplicitSpecialization)) {
+ // All but one template parameter lists have been matching.
+ --NumMatchedTemplateParamLists;
+
if (TemplateParams->size() > 0) {
// This is a function template
@@ -3135,11 +3148,13 @@
<< FixItHint::CreateInsertion(InsertLoc, "<>");
}
}
+ }
- // FIXME: Free this memory properly.
- TemplateParamLists.release();
+ if (NumMatchedTemplateParamLists > 0) {
+ NewFD->setTemplateParameterListsInfo(NumMatchedTemplateParamLists,
+ (TemplateParameterList**)TemplateParamLists.release());
}
-
+
// C++ [dcl.fct.spec]p5:
// The virtual specifier shall only be used in declarations of
// nonstatic class member functions that appear within a
@@ -4965,6 +4980,7 @@
// FIXME: Check explicit specializations more carefully.
bool isExplicitSpecialization = false;
+ unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
if (TUK != TUK_Reference) {
if (TemplateParameterList *TemplateParams
= MatchTemplateParametersToScopeSpecifier(KWLoc, SS,
@@ -4972,6 +4988,9 @@
TemplateParameterLists.size(),
TUK == TUK_Friend,
isExplicitSpecialization)) {
+ // All but one template parameter lists have been matching.
+ --NumMatchedTemplateParamLists;
+
if (TemplateParams->size() > 0) {
// This is a declaration or definition of a class template (which may
// be a member of another template).
@@ -4989,8 +5008,6 @@
isExplicitSpecialization = true;
}
}
-
- TemplateParameterLists.release();
}
DeclContext *SearchDC = CurContext;
@@ -5394,6 +5411,10 @@
NestedNameSpecifier *NNS
= static_cast<NestedNameSpecifier*>(SS.getScopeRep());
New->setQualifierInfo(NNS, SS.getRange());
+ if (NumMatchedTemplateParamLists > 0) {
+ New->setTemplateParameterListsInfo(NumMatchedTemplateParamLists,
+ (TemplateParameterList**) TemplateParameterLists.release());
+ }
}
else
Invalid = true;
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=105882&r1=105881&r2=105882&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sat Jun 12 03:15:14 2010
@@ -3666,6 +3666,10 @@
TemplateParameterLists.size(),
TUK == TUK_Friend,
isExplicitSpecialization);
+ unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
+ if (TemplateParams)
+ --NumMatchedTemplateParamLists;
+
if (TemplateParams && TemplateParams->size() > 0) {
isPartialSpecialization = true;
@@ -3857,6 +3861,10 @@
PrevPartial,
SequenceNumber);
SetNestedNameSpecifier(Partial, SS);
+ if (NumMatchedTemplateParamLists > 0) {
+ Partial->setTemplateParameterListsInfo(NumMatchedTemplateParamLists,
+ (TemplateParameterList**) TemplateParameterLists.release());
+ }
if (PrevPartial) {
ClassTemplate->getPartialSpecializations().RemoveNode(PrevPartial);
@@ -3914,6 +3922,11 @@
Converted,
PrevDecl);
SetNestedNameSpecifier(Specialization, SS);
+ if (NumMatchedTemplateParamLists > 0) {
+ Specialization->setTemplateParameterListsInfo(
+ NumMatchedTemplateParamLists,
+ (TemplateParameterList**) TemplateParameterLists.release());
+ }
if (PrevDecl) {
ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
More information about the cfe-commits
mailing list