Skip to content

Commit 93a6ba5

Browse files
committed
a bunch of work, most of it broken
1 parent 9674f45 commit 93a6ba5

22 files changed

+358
-82
lines changed

clang/include/clang/AST/DeclCXX.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4397,6 +4397,34 @@ class UnnamedGlobalConstantDecl : public ValueDecl,
43974397
/// into a diagnostic with <<.
43984398
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
43994399
AccessSpecifier AS);
4400+
4401+
4402+
/// A result name introduces in a post condition. For instance, given:
4403+
///
4404+
/// int foo() post(r : r > 0);
4405+
///
4406+
/// Where `r` refers to the value returned by the function
4407+
class ResultNameDecl : public ValueDecl {
4408+
4409+
ResultNameDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
4410+
: ValueDecl(Decl::ResultName, DC, IdLoc, Id, T) {}
4411+
4412+
void anchor() override;
4413+
4414+
public:
4415+
friend class ASTDeclReader;
4416+
4417+
static ResultNameDecl *Create(ASTContext &C, DeclContext *DC,
4418+
SourceLocation IdLoc, IdentifierInfo *Id,
4419+
QualType T);
4420+
static ResultNameDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
4421+
4422+
using ValueDecl::getDeclName;
4423+
using ValueDecl::setType;
4424+
4425+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
4426+
static bool classofKind(Kind K) { return K == Decl::ResultName; }
4427+
};
44004428

44014429
} // namespace clang
44024430

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,6 +2147,8 @@ DEF_TRAVERSE_DECL(BindingDecl, {
21472147
TRY_TO(TraverseStmt(D->getBinding()));
21482148
})
21492149

2150+
DEF_TRAVERSE_DECL(ResultNameDecl, {})
2151+
21502152
DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
21512153

21522154
DEF_TRAVERSE_DECL(MSGuidDecl, {})

clang/include/clang/Basic/Attr.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3260,6 +3260,13 @@ def Unavailable : InheritableAttr {
32603260
let MeaningfulToClassTemplateDefinition = 1;
32613261
}
32623262

3263+
def ContractGroup : StmtAttr {
3264+
let Spellings = [CXX11<"clang", "contract_group">];
3265+
let Args = [ StringArgument<"Group">];
3266+
let Subjects = SubjectList<[ContractStmt], ErrorDiag, "contract_assert">;
3267+
let Documentation = [Undocumented];
3268+
}
3269+
32633270
def DiagnoseIf : InheritableAttr {
32643271
// Does not have a [[]] spelling because this attribute requires the ability
32653272
// to parse function arguments but the attribute is not written in the type

clang/include/clang/Basic/DeclNodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def Named : DeclNode<Decl, "named declarations", 1>;
3838
def UnresolvedUsingValue : DeclNode<Value>;
3939
def IndirectField : DeclNode<Value>;
4040
def Binding : DeclNode<Value>;
41+
def ResultName : DeclNode<Value>;
4142
def OMPDeclareReduction : DeclNode<Value>, DeclContext;
4243
def OMPDeclareMapper : DeclNode<Value>, DeclContext;
4344
def MSGuid : DeclNode<Value>;

clang/include/clang/Parse/Parser.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2125,7 +2125,9 @@ class Parser : public CodeCompletionHandler {
21252125
StmtResult ParseContractAssertStatement();
21262126
void MaybeParseFunctionContractSpecifierSeq(Declarator &DeclaratorInfo);
21272127
StmtResult ParseFunctionContractSpecifier(Declarator &DeclaratorInfo);
2128-
void ParsePostContract(Declarator &DeclaratorInfo);
2128+
void MaybeLateParseFunctionContractSpecifierSeq(Declarator &DeclaratorInfo);
2129+
bool LateParseFunctionContractSpecifier(Declarator &DeclaratorInfo, CachedTokens & ContractToks);
2130+
21292131

21302132
//===--------------------------------------------------------------------===//
21312133
// C99 6.7.8: Initialization.

clang/include/clang/Sema/DeclSpec.h

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,33 +1849,34 @@ enum class FunctionDefinitionKind {
18491849
};
18501850

18511851
enum class DeclaratorContext {
1852-
File, // File scope declaration.
1853-
Prototype, // Within a function prototype.
1854-
ObjCResult, // An ObjC method result type.
1855-
ObjCParameter, // An ObjC method parameter type.
1856-
KNRTypeList, // K&R type definition list for formals.
1857-
TypeName, // Abstract declarator for types.
1858-
FunctionalCast, // Type in a C++ functional cast expression.
1859-
Member, // Struct/Union field.
1860-
Block, // Declaration within a block in a function.
1861-
ForInit, // Declaration within first part of a for loop.
1862-
SelectionInit, // Declaration within optional init stmt of if/switch.
1863-
Condition, // Condition declaration in a C++ if/switch/while/for.
1864-
TemplateParam, // Within a template parameter list.
1865-
CXXNew, // C++ new-expression.
1866-
CXXCatch, // C++ catch exception-declaration
1867-
ObjCCatch, // Objective-C catch exception-declaration
1868-
BlockLiteral, // Block literal declarator.
1869-
LambdaExpr, // Lambda-expression declarator.
1870-
LambdaExprParameter, // Lambda-expression parameter declarator.
1871-
ConversionId, // C++ conversion-type-id.
1872-
TrailingReturn, // C++11 trailing-type-specifier.
1873-
TrailingReturnVar, // C++11 trailing-type-specifier for variable.
1874-
TemplateArg, // Any template argument (in template argument list).
1875-
TemplateTypeArg, // Template type argument (in default argument).
1876-
AliasDecl, // C++11 alias-declaration.
1877-
AliasTemplate, // C++11 alias-declaration template.
1878-
RequiresExpr, // C++2a requires-expression.
1852+
File, // File scope declaration.
1853+
Prototype, // Within a function prototype.
1854+
ObjCResult, // An ObjC method result type.
1855+
ObjCParameter, // An ObjC method parameter type.
1856+
KNRTypeList, // K&R type definition list for formals.
1857+
TypeName, // Abstract declarator for types.
1858+
FunctionalCast, // Type in a C++ functional cast expression.
1859+
Member, // Struct/Union field.
1860+
Block, // Declaration within a block in a function.
1861+
ForInit, // Declaration within first part of a for loop.
1862+
SelectionInit, // Declaration within optional init stmt of if/switch.
1863+
Condition, // Condition declaration in a C++ if/switch/while/for.
1864+
TemplateParam, // Within a template parameter list.
1865+
CXXNew, // C++ new-expression.
1866+
CXXCatch, // C++ catch exception-declaration
1867+
ObjCCatch, // Objective-C catch exception-declaration
1868+
BlockLiteral, // Block literal declarator.
1869+
LambdaExpr, // Lambda-expression declarator.
1870+
LambdaExprParameter, // Lambda-expression parameter declarator.
1871+
ConversionId, // C++ conversion-type-id.
1872+
TrailingReturn, // C++11 trailing-type-specifier.
1873+
TrailingReturnVar, // C++11 trailing-type-specifier for variable.
1874+
TemplateArg, // Any template argument (in template argument list).
1875+
TemplateTypeArg, // Template type argument (in default argument).
1876+
AliasDecl, // C++11 alias-declaration.
1877+
AliasTemplate, // C++11 alias-declaration template.
1878+
RequiresExpr, // C++2a requires-expression.
1879+
//ContractPostcondition, // C++2a requires-type. FIXME(EricWF)
18791880
Association // C11 _Generic selection expression association.
18801881
};
18811882

@@ -1973,6 +1974,7 @@ class Declarator {
19731974

19741975
/// \brief All pre and post contracts specified by the function declaration
19751976
SmallVector<ContractStmt *> Contracts;
1977+
SmallVector<CachedTokens> LateParsedContracts;
19761978

19771979
/// If this declarator declares a template, its template parameter lists.
19781980
ArrayRef<TemplateParameterList *> TemplateParameterLists;
@@ -2648,7 +2650,17 @@ class Declarator {
26482650
void addContract(ContractStmt *TRC) { Contracts.push_back(TRC); }
26492651

26502652
/// \brief Get all pre contracts for this declarator
2651-
const SmallVector<ContractStmt *> &getContracts() { return Contracts; }
2653+
const SmallVector<ContractStmt *> &getContracts() {
2654+
return Contracts;
2655+
}
2656+
2657+
void addLateParsedContract(CachedTokens Toks) {
2658+
LateParsedContracts.push_back(Toks);
2659+
}
2660+
2661+
const SmallVector<CachedTokens> &getLateParsedContracts() {
2662+
return LateParsedContracts;
2663+
}
26522664

26532665
/// Sets the template parameter lists that preceded the declarator.
26542666
void setTemplateParameterLists(ArrayRef<TemplateParameterList *> TPLs) {

clang/include/clang/Sema/Scope.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ class Scope {
162162

163163
/// This is a scope of friend declaration.
164164
FriendScope = 0x40000000,
165+
166+
/// The scope introduced by a post condition on a function declaration
167+
PostConditionScope = 0x80000000,
165168
};
166169

167170
private:
@@ -563,6 +566,10 @@ class Scope {
563566
return getFlags() & ScopeFlags::ContinueScope;
564567
}
565568

569+
bool isPostConditionScope() const {
570+
return getFlags() & ScopeFlags::PostConditionScope;
571+
}
572+
566573
/// Determine whether this scope is a C++ 'try' block.
567574
bool isTryScope() const { return getFlags() & Scope::TryScope; }
568575

clang/include/clang/Sema/Sema.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2732,6 +2732,12 @@ class Sema final : public SemaBase {
27322732
StmtResult ActOnPreContractAssert(SourceLocation KeywordLoc, Expr *Cond);
27332733
StmtResult ActOnPostContractAssert(SourceLocation KeywordLoc, Expr *Cond,
27342734
DeclStmt *ResultNameDecl = nullptr);
2735+
StmtResult BuildResultNameDecl(DeclContext* DC, SourceLocation Loc, IdentifierInfo *Id, QualType T);
2736+
void ActOnStartContracts(Scope *S, Declarator& D);
2737+
StmtResult ActOnResultNameDeclarator(Scope *S, Declarator &FuncDecl,
2738+
SourceLocation IDLoc,
2739+
IdentifierInfo *II);
2740+
27352741

27362742
ExprResult ActOnContractAssertCondition(Expr *Cond);
27372743

clang/lib/AST/DeclBase.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,10 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
890890
// tag types, so we include them in the tag namespace.
891891
return IDNS_Ordinary | IDNS_Tag;
892892

893+
// FIXME(EricWF): IDK if this is correct
894+
case ResultName:
895+
return IDNS_Ordinary | IDNS_Tag;
896+
893897
case ObjCCompatibleAlias:
894898
case ObjCInterface:
895899
return IDNS_Ordinary | IDNS_Type;

clang/lib/AST/DeclCXX.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3568,3 +3568,14 @@ const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
35683568
AccessSpecifier AS) {
35693569
return DB << getAccessName(AS);
35703570
}
3571+
3572+
ResultNameDecl *ResultNameDecl::Create(ASTContext &C, DeclContext *DC,
3573+
SourceLocation IdLoc, IdentifierInfo *Id, QualType T) {
3574+
return new (C, DC) ResultNameDecl(DC, IdLoc, Id, T);
3575+
}
3576+
3577+
ResultNameDecl *ResultNameDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
3578+
return new (C, ID) ResultNameDecl(nullptr, SourceLocation(), nullptr, QualType());
3579+
}
3580+
3581+
void ResultNameDecl::anchor() {}

0 commit comments

Comments
 (0)